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"
2003-01-09 09:53:34 +03:00
# include <signal.h>
# include <sys/syscall.h>
1999-02-19 03:21:36 +03:00
# include <sys/user.h>
# include <sys/param.h>
# include <fcntl.h>
2001-07-10 17:48:44 +04:00
# if HAVE_SYS_UIO_H
# include <sys/uio.h>
# endif
1999-02-19 03:21:36 +03:00
# ifdef SUNOS4
# include <machine/reg.h>
# include <a.out.h>
# include <link.h>
# endif /* SUNOS4 */
1999-07-13 19:45:02 +04:00
2000-06-27 21:33:32 +04:00
# if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
1999-02-19 03:21:36 +03:00
# include <linux/ptrace.h>
2002-12-16 23:40:54 +03:00
# endif
1999-07-13 19:45:02 +04:00
2000-02-04 00:58:30 +03:00
# if defined(LINUX) && defined(IA64)
2003-01-09 09:53:34 +03:00
# include <asm / ptrace_offsets.h>
# include <asm / rse.h>
2000-02-04 00:58:30 +03:00
# endif
1999-07-13 19:45:02 +04:00
# ifdef HAVE_SYS_REG_H
# include <sys/reg.h>
# define PTRACE_PEEKUSR PTRACE_PEEKUSER
2000-02-20 02:59:03 +03:00
# elif defined(HAVE_LINUX_PTRACE_H)
# undef PTRACE_SYSCALL
2004-03-02 00:29:22 +03:00
# ifdef HAVE_STRUCT_IA64_FPREG
# define ia64_fpreg XXX_ia64_fpreg
# endif
# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
# define pt_all_user_regs XXX_pt_all_user_regs
# endif
2000-02-20 02:59:03 +03:00
# include <linux/ptrace.h>
2004-03-02 00:29:22 +03:00
# undef ia64_fpreg
# undef pt_all_user_regs
1999-05-09 04:29:58 +04:00
# endif
1999-02-19 03:21:36 +03:00
# ifdef SUNOS4_KERNEL_ARCH_KLUDGE
# include <sys/utsname.h>
# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# if defined(LINUXSPARC)
1999-08-30 03:15:07 +04:00
2003-01-30 23:15:19 +03:00
# define fpq kernel_fpq
# define fq kernel_fq
# define fpu kernel_fpu
# include <asm / reg.h>
# undef fpq
# undef fq
# undef fpu
1999-08-30 03:15:07 +04:00
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# if defined (SPARC64)
# define r_pc r_tpc
# undef PTRACE_GETREGS
# define PTRACE_GETREGS PTRACE_GETREGS64
# undef PTRACE_SETREGS
# define PTRACE_SETREGS PTRACE_SETREGS64
# endif /* SPARC64 */
1999-08-30 03:15:07 +04:00
# if !defined(__GLIBC__)
1999-02-19 03:21:36 +03:00
# include <linux/unistd.h>
# define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
type5 , arg5 , syscall ) \
type name ( type1 arg1 , type2 arg2 , type3 arg3 , type4 arg4 , type5 arg5 ) \
{ \
long __res ; \
\
__asm__ volatile ( " or %%g0, %1, %%o0 \n \t " \
" or %%g0, %2, %%o1 \n \t " \
" or %%g0, %3, %%o2 \n \t " \
" or %%g0, %4, %%o3 \n \t " \
" or %%g0, %5, %%o4 \n \t " \
" or %%g0, %6, %%g1 \n \t " \
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# if defined (SPARC64)
" t 0x6d \n \t " \
# else
1999-02-19 03:21:36 +03:00
" t 0x10 \n \t " \
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# endif
1999-02-19 03:21:36 +03:00
" bcc 1f \n \t " \
" or %%g0, %%o0, %0 \n \t " \
" sub %%g0, %%o0, %0 \n \t " \
" 1: \n \t " \
: " =r " ( __res ) \
: " 0 " ( ( long ) ( arg1 ) ) , " 1 " ( ( long ) ( arg2 ) ) , \
" 2 " ( ( long ) ( arg3 ) ) , " 3 " ( ( long ) ( arg4 ) ) , " 4 " ( ( long ) ( arg5 ) ) , \
" i " ( __NR_ # # syscall ) \
: " g1 " , " o0 " , " o1 " , " o2 " , " o3 " , " o4 " ) ; \
if ( __res > = 0 ) \
return ( type ) __res ; \
errno = - __res ; \
return - 1 ; \
}
static _hack_syscall5 ( int , _ptrace , int , __request , int , __pid , int , __addr , int , __data , int , __addr2 , ptrace )
# define _ptrace
# endif
1999-08-30 03:15:07 +04:00
# endif
1999-02-19 03:21:36 +03:00
/* macros */
# ifndef MAX
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
# endif
# ifndef MIN
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
# endif
2005-06-09 00:45:28 +04:00
#if 0
1999-02-19 03:21:36 +03:00
void
tv_tv ( tv , a , b )
struct timeval * tv ;
int a ;
int b ;
{
tv - > tv_sec = a ;
tv - > tv_usec = b ;
}
2005-06-09 00:45:28 +04:00
# endif
1999-02-19 03:21:36 +03:00
int
tv_nz ( a )
struct timeval * a ;
{
return a - > tv_sec | | a - > tv_usec ;
}
int
tv_cmp ( a , b )
struct timeval * a , * b ;
{
if ( a - > tv_sec < b - > tv_sec
| | ( a - > tv_sec = = b - > tv_sec & & a - > tv_usec < b - > tv_usec ) )
return - 1 ;
if ( a - > tv_sec > b - > tv_sec
| | ( a - > tv_sec = = b - > tv_sec & & a - > tv_usec > b - > tv_usec ) )
return 1 ;
return 0 ;
}
double
tv_float ( tv )
struct timeval * tv ;
{
return tv - > tv_sec + tv - > tv_usec / 1000000.0 ;
}
void
tv_add ( tv , a , b )
struct timeval * tv , * a , * b ;
{
tv - > tv_sec = a - > tv_sec + b - > tv_sec ;
tv - > tv_usec = a - > tv_usec + b - > tv_usec ;
2007-07-24 05:38:22 +04:00
if ( tv - > tv_usec > = 1000000 ) {
1999-02-19 03:21:36 +03:00
tv - > tv_sec + + ;
tv - > tv_usec - = 1000000 ;
}
}
void
tv_sub ( tv , a , b )
struct timeval * tv , * a , * b ;
{
tv - > tv_sec = a - > tv_sec - b - > tv_sec ;
tv - > tv_usec = a - > tv_usec - b - > tv_usec ;
if ( ( ( long ) tv - > tv_usec ) < 0 ) {
tv - > tv_sec - - ;
tv - > tv_usec + = 1000000 ;
}
}
void
tv_div ( tv , a , n )
struct timeval * tv , * a ;
int n ;
{
tv - > tv_usec = ( a - > tv_sec % n * 1000000 + a - > tv_usec + n / 2 ) / n ;
tv - > tv_sec = a - > tv_sec / n + tv - > tv_usec / 1000000 ;
tv - > tv_usec % = 1000000 ;
}
void
tv_mul ( tv , a , n )
struct timeval * tv , * a ;
int n ;
{
tv - > tv_usec = a - > tv_usec * n ;
2007-06-30 01:25:56 +04:00
tv - > tv_sec = a - > tv_sec * n + tv - > tv_usec / 1000000 ;
1999-02-19 03:21:36 +03:00
tv - > tv_usec % = 1000000 ;
}
2007-01-12 01:05:04 +03:00
const char *
xlookup ( const struct xlat * xlat , int val )
1999-02-19 03:21:36 +03:00
{
for ( ; xlat - > str ! = NULL ; xlat + + )
if ( xlat - > val = = val )
return xlat - > str ;
return NULL ;
}
2008-12-17 22:21:59 +03:00
/*
* Generic ptrace wrapper which tracks ESRCH errors
* by setting tcp - > ptrace_errno to ESRCH .
*
* We assume that ESRCH indicates likely process death ( SIGKILL ? ) ,
* modulo bugs where process somehow ended up not stopped .
* Unfortunately kernel uses ESRCH for that case too . Oh well .
*
* Currently used by upeek ( ) only .
* TODO : use this in all other ptrace ( ) calls while decoding .
*/
long
do_ptrace ( int request , struct tcb * tcp , void * addr , void * data )
{
long l ;
errno = 0 ;
l = ptrace ( request , tcp - > pid , addr , data ) ;
/* Non-ESRCH errors might be our invalid reg/mem accesses,
* we do not record them . */
if ( errno = = ESRCH )
tcp - > ptrace_errno = ESRCH ;
return l ;
}
/*
* Used when we want to unblock stopped traced process .
* Should be only used with PTRACE_CONT , PTRACE_DETACH and PTRACE_SYSCALL .
* Returns 0 on success or if error was ESRCH
* ( presumably process was killed while we talk to it ) .
* Otherwise prints error message and returns - 1.
*/
int
ptrace_restart ( int op , struct tcb * tcp , int sig )
{
int err ;
const char * msg ;
errno = 0 ;
ptrace ( op , tcp - > pid , ( void * ) 1 , ( void * ) ( long ) sig ) ;
err = errno ;
if ( ! err | | err = = ESRCH )
return 0 ;
tcp - > ptrace_errno = err ;
msg = " SYSCALL " ;
if ( op = = PTRACE_CONT )
msg = " CONT " ;
if ( op = = PTRACE_DETACH )
msg = " DETACH " ;
fprintf ( stderr , " strace: ptrace(PTRACE_%s,1,%d): %s \n " ,
msg , sig , strerror ( err ) ) ;
return - 1 ;
}
1999-02-19 03:21:36 +03:00
/*
* Print entry in struct xlat table , if there .
*/
void
2007-01-12 01:05:04 +03:00
printxval ( const struct xlat * xlat , int val , const char * dflt )
1999-02-19 03:21:36 +03:00
{
2007-01-12 01:05:04 +03:00
const char * str = xlookup ( xlat , val ) ;
1999-02-19 03:21:36 +03:00
if ( str )
tprintf ( " %s " , str ) ;
else
tprintf ( " %#x /* %s */ " , val , dflt ) ;
}
/*
* Interpret ` xlat ' as an array of flags
* print the entries whose bits are on in ` flags '
* return # of flags printed .
*/
int
addflags ( xlat , flags )
2004-09-04 07:39:20 +04:00
const struct xlat * xlat ;
1999-02-19 03:21:36 +03:00
int flags ;
{
int n ;
for ( n = 0 ; xlat - > str ; xlat + + ) {
if ( xlat - > val & & ( flags & xlat - > val ) = = xlat - > val ) {
tprintf ( " |%s " , xlat - > str ) ;
flags & = ~ xlat - > val ;
n + + ;
}
}
if ( flags ) {
tprintf ( " |%#x " , flags ) ;
n + + ;
}
return n ;
}
2007-11-02 00:46:22 +03:00
/*
* Interpret ` xlat ' as an array of flags /
* Print to static string the entries whose bits are on in ` flags '
* Return static string .
*/
const char *
sprintflags ( const char * prefix , const struct xlat * xlat , int flags )
{
static char outstr [ 1024 ] ;
int found = 0 ;
strcpy ( outstr , prefix ) ;
for ( ; xlat - > str ; xlat + + ) {
if ( ( flags & xlat - > val ) = = xlat - > val ) {
if ( found )
strcat ( outstr , " | " ) ;
strcat ( outstr , xlat - > str ) ;
flags & = ~ xlat - > val ;
found = 1 ;
}
}
if ( flags ) {
if ( found )
strcat ( outstr , " | " ) ;
sprintf ( outstr + strlen ( outstr ) , " %#x " , flags ) ;
}
return outstr ;
}
1999-02-19 03:21:36 +03:00
int
2005-05-31 Dmitry V. Levin <ldv@altlinux.org>
* util.c (printxval): Change third argument from "char *" to
"const char *".
(printflags): Add third argument, "const char *", with similar
meaning to the third argument of printxval().
* defs.h (printxval): Change third argument from "char *" to
"const char *".
(printflags): Add third argument.
* bjm.c (sys_query_module) [LINUX]: Pass third argument to
printflags().
* desc.c (sys_fcntl): Likewise.
(sys_flock) [LOCK_SH]: Likewise.
(print_epoll_event) [HAVE_SYS_EPOLL_H]: Likewise.
* file.c (sys_open): Likewise.
(solaris_open) [LINUXSPARC]: Likewise.
(sys_access): Likewise.
(sys_chflags, sys_fchflags) [FREEBSD]: Likewise.
(realprintstat) [HAVE_LONG_LONG_OFF_T &&
HAVE_STRUCT_STAT_ST_FLAGS]: Likewise.
(printstat64) [HAVE_STAT64 &&
HAVE_STRUCT_STAT_ST_FLAGS]: Likewise.
(sys_setxattr, sys_fsetxattr): Likewise.
* ipc.c (sys_msgget, sys_msgsnd, sys_msgrcv, sys_semget,
sys_shmget, sys_shmat) [LINUX || SUNOS4 || FREEBSD]: Likewise.
(sys_mq_open) [LINUX]: Likewise.
(printmqattr) [HAVE_MQUEUE_H]: Likewise.
* mem.c (print_mmap) [!HAVE_LONG_LONG_OFF_T]: Likewise.
(sys_mmap64) [_LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T]: Likewise.
(sys_mprotect): Likewise.
(sys_mremap, sys_madvise, sys_mlockall) [LINUX]: Likewise.
(sys_msync) [MS_ASYNC]: Likewise.
(sys_mctl) [MC_SYNC]: Likewise.
(sys_remap_file_pages, sys_mbind, sys_get_mempolicy) [LINUX]:
Likewise.
* net.c (printmsghdr) [HAVE_STRUCT_MSGHDR_MSG_CONTROL]: Likewise.
(sys_send, sys_sendto): Likewise.
(sys_sendmsg) [HAVE_SENDMSG]: Likewise.
(sys_recv, sys_recvfrom): Likewise.
(sys_recvmsg) [HAVE_SENDMSG]: Likewise.
(printicmpfilter) [ICMP_FILTER]: Likewise.
* proc.c (proc_ioctl) [SVR4 && !HAVE_MP_PROCFS || FREEBSD]: Likewise.
* process.c (sys_clone) [LINUX]: Likewise.
(printwaitn): Likewise.
(sys_waitid) [SVR4 || LINUX]: Likewise.
* signal.c (sys_sigvec) [SUNOS4 || FREEBSD]: Likewise.
(sys_sigaction): Likewise.
(printcontext) [SVR4]: Likewise.
(print_stack_t) [LINUX) || FREEBSD]: Likewise.
(sys_rt_sigaction) [LINUX]: Likewise.
* sock.c (sock_ioctl) [LINUX]: Likewise.
* stream.c (sys_putmsg, sys_getmsg): Likewise.
(sys_putpmsg) [SYS_putpmsg]: Likewise.
(sys_getpmsg) [SYS_getpmsg]: Likewise.
(sys_poll): Likewise.
(print_transport_message) [TI_BIND]: Likewise.
(stream_ioctl): Likewise.
* system.c (sys_mount, sys_reboot): Likewise.
(sys_cacheflush) [LINUX && M68K]: Likewise.
(sys_capget, sys_capset) [SYS_capget]: Likewise.
* term.c (term_ioctl) [TIOCMGET]: Likewise.
* time.c (sys_clock_nanosleep, sys_timer_settime) [LINUX]:
Likewise.
Fixes RH#159310.
2005-06-01 23:02:36 +04:00
printflags ( xlat , flags , dflt )
2004-09-04 07:39:20 +04:00
const struct xlat * xlat ;
1999-02-19 03:21:36 +03:00
int flags ;
2005-05-31 Dmitry V. Levin <ldv@altlinux.org>
* util.c (printxval): Change third argument from "char *" to
"const char *".
(printflags): Add third argument, "const char *", with similar
meaning to the third argument of printxval().
* defs.h (printxval): Change third argument from "char *" to
"const char *".
(printflags): Add third argument.
* bjm.c (sys_query_module) [LINUX]: Pass third argument to
printflags().
* desc.c (sys_fcntl): Likewise.
(sys_flock) [LOCK_SH]: Likewise.
(print_epoll_event) [HAVE_SYS_EPOLL_H]: Likewise.
* file.c (sys_open): Likewise.
(solaris_open) [LINUXSPARC]: Likewise.
(sys_access): Likewise.
(sys_chflags, sys_fchflags) [FREEBSD]: Likewise.
(realprintstat) [HAVE_LONG_LONG_OFF_T &&
HAVE_STRUCT_STAT_ST_FLAGS]: Likewise.
(printstat64) [HAVE_STAT64 &&
HAVE_STRUCT_STAT_ST_FLAGS]: Likewise.
(sys_setxattr, sys_fsetxattr): Likewise.
* ipc.c (sys_msgget, sys_msgsnd, sys_msgrcv, sys_semget,
sys_shmget, sys_shmat) [LINUX || SUNOS4 || FREEBSD]: Likewise.
(sys_mq_open) [LINUX]: Likewise.
(printmqattr) [HAVE_MQUEUE_H]: Likewise.
* mem.c (print_mmap) [!HAVE_LONG_LONG_OFF_T]: Likewise.
(sys_mmap64) [_LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T]: Likewise.
(sys_mprotect): Likewise.
(sys_mremap, sys_madvise, sys_mlockall) [LINUX]: Likewise.
(sys_msync) [MS_ASYNC]: Likewise.
(sys_mctl) [MC_SYNC]: Likewise.
(sys_remap_file_pages, sys_mbind, sys_get_mempolicy) [LINUX]:
Likewise.
* net.c (printmsghdr) [HAVE_STRUCT_MSGHDR_MSG_CONTROL]: Likewise.
(sys_send, sys_sendto): Likewise.
(sys_sendmsg) [HAVE_SENDMSG]: Likewise.
(sys_recv, sys_recvfrom): Likewise.
(sys_recvmsg) [HAVE_SENDMSG]: Likewise.
(printicmpfilter) [ICMP_FILTER]: Likewise.
* proc.c (proc_ioctl) [SVR4 && !HAVE_MP_PROCFS || FREEBSD]: Likewise.
* process.c (sys_clone) [LINUX]: Likewise.
(printwaitn): Likewise.
(sys_waitid) [SVR4 || LINUX]: Likewise.
* signal.c (sys_sigvec) [SUNOS4 || FREEBSD]: Likewise.
(sys_sigaction): Likewise.
(printcontext) [SVR4]: Likewise.
(print_stack_t) [LINUX) || FREEBSD]: Likewise.
(sys_rt_sigaction) [LINUX]: Likewise.
* sock.c (sock_ioctl) [LINUX]: Likewise.
* stream.c (sys_putmsg, sys_getmsg): Likewise.
(sys_putpmsg) [SYS_putpmsg]: Likewise.
(sys_getpmsg) [SYS_getpmsg]: Likewise.
(sys_poll): Likewise.
(print_transport_message) [TI_BIND]: Likewise.
(stream_ioctl): Likewise.
* system.c (sys_mount, sys_reboot): Likewise.
(sys_cacheflush) [LINUX && M68K]: Likewise.
(sys_capget, sys_capset) [SYS_capget]: Likewise.
* term.c (term_ioctl) [TIOCMGET]: Likewise.
* time.c (sys_clock_nanosleep, sys_timer_settime) [LINUX]:
Likewise.
Fixes RH#159310.
2005-06-01 23:02:36 +04:00
const char * dflt ;
1999-02-19 03:21:36 +03:00
{
int n ;
char * sep ;
if ( flags = = 0 & & xlat - > val = = 0 ) {
tprintf ( " %s " , xlat - > str ) ;
return 1 ;
}
sep = " " ;
for ( n = 0 ; xlat - > str ; xlat + + ) {
if ( xlat - > val & & ( flags & xlat - > val ) = = xlat - > val ) {
tprintf ( " %s%s " , sep , xlat - > str ) ;
flags & = ~ xlat - > val ;
sep = " | " ;
n + + ;
}
}
2005-05-31 Dmitry V. Levin <ldv@altlinux.org>
* util.c (printxval): Change third argument from "char *" to
"const char *".
(printflags): Add third argument, "const char *", with similar
meaning to the third argument of printxval().
* defs.h (printxval): Change third argument from "char *" to
"const char *".
(printflags): Add third argument.
* bjm.c (sys_query_module) [LINUX]: Pass third argument to
printflags().
* desc.c (sys_fcntl): Likewise.
(sys_flock) [LOCK_SH]: Likewise.
(print_epoll_event) [HAVE_SYS_EPOLL_H]: Likewise.
* file.c (sys_open): Likewise.
(solaris_open) [LINUXSPARC]: Likewise.
(sys_access): Likewise.
(sys_chflags, sys_fchflags) [FREEBSD]: Likewise.
(realprintstat) [HAVE_LONG_LONG_OFF_T &&
HAVE_STRUCT_STAT_ST_FLAGS]: Likewise.
(printstat64) [HAVE_STAT64 &&
HAVE_STRUCT_STAT_ST_FLAGS]: Likewise.
(sys_setxattr, sys_fsetxattr): Likewise.
* ipc.c (sys_msgget, sys_msgsnd, sys_msgrcv, sys_semget,
sys_shmget, sys_shmat) [LINUX || SUNOS4 || FREEBSD]: Likewise.
(sys_mq_open) [LINUX]: Likewise.
(printmqattr) [HAVE_MQUEUE_H]: Likewise.
* mem.c (print_mmap) [!HAVE_LONG_LONG_OFF_T]: Likewise.
(sys_mmap64) [_LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T]: Likewise.
(sys_mprotect): Likewise.
(sys_mremap, sys_madvise, sys_mlockall) [LINUX]: Likewise.
(sys_msync) [MS_ASYNC]: Likewise.
(sys_mctl) [MC_SYNC]: Likewise.
(sys_remap_file_pages, sys_mbind, sys_get_mempolicy) [LINUX]:
Likewise.
* net.c (printmsghdr) [HAVE_STRUCT_MSGHDR_MSG_CONTROL]: Likewise.
(sys_send, sys_sendto): Likewise.
(sys_sendmsg) [HAVE_SENDMSG]: Likewise.
(sys_recv, sys_recvfrom): Likewise.
(sys_recvmsg) [HAVE_SENDMSG]: Likewise.
(printicmpfilter) [ICMP_FILTER]: Likewise.
* proc.c (proc_ioctl) [SVR4 && !HAVE_MP_PROCFS || FREEBSD]: Likewise.
* process.c (sys_clone) [LINUX]: Likewise.
(printwaitn): Likewise.
(sys_waitid) [SVR4 || LINUX]: Likewise.
* signal.c (sys_sigvec) [SUNOS4 || FREEBSD]: Likewise.
(sys_sigaction): Likewise.
(printcontext) [SVR4]: Likewise.
(print_stack_t) [LINUX) || FREEBSD]: Likewise.
(sys_rt_sigaction) [LINUX]: Likewise.
* sock.c (sock_ioctl) [LINUX]: Likewise.
* stream.c (sys_putmsg, sys_getmsg): Likewise.
(sys_putpmsg) [SYS_putpmsg]: Likewise.
(sys_getpmsg) [SYS_getpmsg]: Likewise.
(sys_poll): Likewise.
(print_transport_message) [TI_BIND]: Likewise.
(stream_ioctl): Likewise.
* system.c (sys_mount, sys_reboot): Likewise.
(sys_cacheflush) [LINUX && M68K]: Likewise.
(sys_capget, sys_capset) [SYS_capget]: Likewise.
* term.c (term_ioctl) [TIOCMGET]: Likewise.
* time.c (sys_clock_nanosleep, sys_timer_settime) [LINUX]:
Likewise.
Fixes RH#159310.
2005-06-01 23:02:36 +04:00
if ( n ) {
if ( flags ) {
tprintf ( " %s%#x " , sep , flags ) ;
n + + ;
}
} else {
if ( flags ) {
tprintf ( " %#x " , flags ) ;
if ( dflt )
tprintf ( " /* %s */ " , dflt ) ;
} else {
if ( dflt )
tprintf ( " 0 " ) ;
}
1999-02-19 03:21:36 +03:00
}
2005-05-31 Dmitry V. Levin <ldv@altlinux.org>
* util.c (printxval): Change third argument from "char *" to
"const char *".
(printflags): Add third argument, "const char *", with similar
meaning to the third argument of printxval().
* defs.h (printxval): Change third argument from "char *" to
"const char *".
(printflags): Add third argument.
* bjm.c (sys_query_module) [LINUX]: Pass third argument to
printflags().
* desc.c (sys_fcntl): Likewise.
(sys_flock) [LOCK_SH]: Likewise.
(print_epoll_event) [HAVE_SYS_EPOLL_H]: Likewise.
* file.c (sys_open): Likewise.
(solaris_open) [LINUXSPARC]: Likewise.
(sys_access): Likewise.
(sys_chflags, sys_fchflags) [FREEBSD]: Likewise.
(realprintstat) [HAVE_LONG_LONG_OFF_T &&
HAVE_STRUCT_STAT_ST_FLAGS]: Likewise.
(printstat64) [HAVE_STAT64 &&
HAVE_STRUCT_STAT_ST_FLAGS]: Likewise.
(sys_setxattr, sys_fsetxattr): Likewise.
* ipc.c (sys_msgget, sys_msgsnd, sys_msgrcv, sys_semget,
sys_shmget, sys_shmat) [LINUX || SUNOS4 || FREEBSD]: Likewise.
(sys_mq_open) [LINUX]: Likewise.
(printmqattr) [HAVE_MQUEUE_H]: Likewise.
* mem.c (print_mmap) [!HAVE_LONG_LONG_OFF_T]: Likewise.
(sys_mmap64) [_LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T]: Likewise.
(sys_mprotect): Likewise.
(sys_mremap, sys_madvise, sys_mlockall) [LINUX]: Likewise.
(sys_msync) [MS_ASYNC]: Likewise.
(sys_mctl) [MC_SYNC]: Likewise.
(sys_remap_file_pages, sys_mbind, sys_get_mempolicy) [LINUX]:
Likewise.
* net.c (printmsghdr) [HAVE_STRUCT_MSGHDR_MSG_CONTROL]: Likewise.
(sys_send, sys_sendto): Likewise.
(sys_sendmsg) [HAVE_SENDMSG]: Likewise.
(sys_recv, sys_recvfrom): Likewise.
(sys_recvmsg) [HAVE_SENDMSG]: Likewise.
(printicmpfilter) [ICMP_FILTER]: Likewise.
* proc.c (proc_ioctl) [SVR4 && !HAVE_MP_PROCFS || FREEBSD]: Likewise.
* process.c (sys_clone) [LINUX]: Likewise.
(printwaitn): Likewise.
(sys_waitid) [SVR4 || LINUX]: Likewise.
* signal.c (sys_sigvec) [SUNOS4 || FREEBSD]: Likewise.
(sys_sigaction): Likewise.
(printcontext) [SVR4]: Likewise.
(print_stack_t) [LINUX) || FREEBSD]: Likewise.
(sys_rt_sigaction) [LINUX]: Likewise.
* sock.c (sock_ioctl) [LINUX]: Likewise.
* stream.c (sys_putmsg, sys_getmsg): Likewise.
(sys_putpmsg) [SYS_putpmsg]: Likewise.
(sys_getpmsg) [SYS_getpmsg]: Likewise.
(sys_poll): Likewise.
(print_transport_message) [TI_BIND]: Likewise.
(stream_ioctl): Likewise.
* system.c (sys_mount, sys_reboot): Likewise.
(sys_cacheflush) [LINUX && M68K]: Likewise.
(sys_capget, sys_capset) [SYS_capget]: Likewise.
* term.c (term_ioctl) [TIOCMGET]: Likewise.
* time.c (sys_clock_nanosleep, sys_timer_settime) [LINUX]:
Likewise.
Fixes RH#159310.
2005-06-01 23:02:36 +04:00
1999-02-19 03:21:36 +03:00
return n ;
}
void
printnum ( tcp , addr , fmt )
struct tcb * tcp ;
long addr ;
char * fmt ;
{
2003-01-14 12:59:00 +03:00
long num ;
1999-02-19 03:21:36 +03:00
if ( ! addr ) {
tprintf ( " NULL " ) ;
return ;
}
if ( umove ( tcp , addr , & num ) < 0 ) {
tprintf ( " %#lx " , addr ) ;
return ;
}
tprintf ( " [ " ) ;
tprintf ( fmt , num ) ;
tprintf ( " ] " ) ;
}
2005-07-05 03:28:10 +04:00
void
printnum_int ( tcp , addr , fmt )
struct tcb * tcp ;
long addr ;
char * fmt ;
{
int num ;
if ( ! addr ) {
tprintf ( " NULL " ) ;
return ;
}
if ( umove ( tcp , addr , & num ) < 0 ) {
tprintf ( " %#lx " , addr ) ;
return ;
}
tprintf ( " [ " ) ;
tprintf ( fmt , num ) ;
tprintf ( " ] " ) ;
}
2003-11-14 01:32:27 +03:00
void
printuid ( text , uid )
const char * text ;
unsigned long uid ;
{
tprintf ( " %s " , text ) ;
tprintf ( ( uid = = - 1 ) ? " %ld " : " %lu " , uid ) ;
}
1999-02-19 03:21:36 +03:00
static char path [ MAXPATHLEN + 1 ] ;
2008-11-11 02:19:13 +03:00
/*
* Quote string ` instr ' of length ` size '
* Write up to ( 3 + ` size ' * 4 ) bytes to ` outstr ' buffer .
* If ` len ' < 0 , treat ` instr ' as a NUL - terminated string
* and quote at most ( ` size ' - 1 ) bytes .
*/
2007-11-02 02:53:59 +03:00
static int
2007-10-09 01:48:01 +04:00
string_quote ( const char * instr , char * outstr , int len , int size )
1999-02-19 03:21:36 +03:00
{
2007-10-09 01:48:01 +04:00
const unsigned char * ustr = ( const unsigned char * ) instr ;
char * s = outstr ;
int usehex = 0 , c , i ;
1999-02-19 03:21:36 +03:00
2007-10-09 01:48:01 +04:00
if ( xflag > 1 )
usehex = 1 ;
else if ( xflag ) {
2008-11-11 02:19:13 +03:00
/* Check for presence of symbol which require
to hex - quote the whole string . */
2007-10-09 01:48:01 +04:00
for ( i = 0 ; i < size ; + + i ) {
c = ustr [ i ] ;
2008-11-11 02:19:13 +03:00
/* Check for NUL-terminated string. */
if ( len < 0 ) {
if ( c = = ' \0 ' )
break ;
/* Quote at most size - 1 bytes. */
if ( i = = size - 1 )
continue ;
}
2007-10-09 01:48:01 +04:00
if ( ! isprint ( c ) & & ! isspace ( c ) ) {
usehex = 1 ;
break ;
}
}
1999-02-19 03:21:36 +03:00
}
2007-10-09 01:48:01 +04:00
* s + + = ' \" ' ;
if ( usehex ) {
2008-11-11 02:19:13 +03:00
/* Hex-quote the whole string. */
2007-10-09 01:48:01 +04:00
for ( i = 0 ; i < size ; + + i ) {
c = ustr [ i ] ;
2008-11-11 02:19:13 +03:00
/* Check for NUL-terminated string. */
if ( len < 0 ) {
if ( c = = ' \0 ' )
break ;
/* Quote at most size - 1 bytes. */
if ( i = = size - 1 )
continue ;
}
2007-10-09 01:48:01 +04:00
sprintf ( s , " \\ x%02x " , c ) ;
s + = 4 ;
}
} else {
for ( i = 0 ; i < size ; + + i ) {
c = ustr [ i ] ;
2008-11-11 02:19:13 +03:00
/* Check for NUL-terminated string. */
if ( len < 0 ) {
if ( c = = ' \0 ' )
break ;
/* Quote at most size - 1 bytes. */
if ( i = = size - 1 )
continue ;
}
2007-10-09 01:48:01 +04:00
switch ( c ) {
case ' \" ' : case ' \\ ' :
* s + + = ' \\ ' ;
* s + + = c ;
break ;
case ' \f ' :
* s + + = ' \\ ' ;
* s + + = ' f ' ;
break ;
case ' \n ' :
* s + + = ' \\ ' ;
* s + + = ' n ' ;
break ;
case ' \r ' :
* s + + = ' \\ ' ;
* s + + = ' r ' ;
break ;
case ' \t ' :
* s + + = ' \\ ' ;
* s + + = ' t ' ;
break ;
case ' \v ' :
* s + + = ' \\ ' ;
* s + + = ' v ' ;
break ;
default :
if ( isprint ( c ) )
* s + + = c ;
else if ( i + 1 < size
& & isdigit ( ustr [ i + 1 ] ) ) {
sprintf ( s , " \\ %03o " , c ) ;
s + = 4 ;
} else {
sprintf ( s , " \\ %o " , c ) ;
s + = strlen ( s ) ;
}
break ;
}
1999-02-19 03:21:36 +03:00
}
}
2007-10-09 01:48:01 +04:00
* s + + = ' \" ' ;
* s = ' \0 ' ;
2007-11-02 02:53:59 +03:00
/* Return nonzero if the string was unterminated. */
return i = = size ;
1999-02-19 03:21:36 +03:00
}
2008-11-11 02:19:13 +03:00
/*
* Print path string specified by address ` addr ' and length ` n ' .
* If path length exceeds ` n ' , append ` . . . ' to the output .
*/
1999-02-19 03:21:36 +03:00
void
2007-10-09 01:48:01 +04:00
printpathn ( struct tcb * tcp , long addr , int n )
1999-02-19 03:21:36 +03:00
{
2008-11-11 02:19:13 +03:00
if ( ! addr ) {
2005-02-06 04:55:07 +03:00
tprintf ( " NULL " ) ;
2007-10-09 01:48:01 +04:00
return ;
}
2008-11-11 02:19:13 +03:00
/* Cap path length to the path buffer size,
and NUL - terminate the buffer . */
if ( n > sizeof path - 1 )
n = sizeof path - 1 ;
2007-10-09 01:48:01 +04:00
path [ n ] = ' \0 ' ;
2008-11-11 02:19:13 +03:00
/* Fetch one byte more to find out whether path length > n. */
2007-10-09 01:48:01 +04:00
if ( umovestr ( tcp , addr , n + 1 , path ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , addr ) ;
else {
2007-10-09 01:48:01 +04:00
static char outstr [ 4 * ( sizeof path - 1 ) + sizeof " \" ... \" " ] ;
int trunc = ( path [ n ] ! = ' \0 ' ) ;
if ( trunc )
path [ n ] = ' \0 ' ;
2008-11-11 02:19:13 +03:00
( void ) string_quote ( path , outstr , - 1 , n + 1 ) ;
if ( trunc )
2007-10-09 01:48:01 +04:00
strcat ( outstr , " ... " ) ;
tprintf ( " %s " , outstr ) ;
1999-02-19 03:21:36 +03:00
}
}
void
2007-10-09 01:48:01 +04:00
printpath ( struct tcb * tcp , long addr )
{
printpathn ( tcp , addr , sizeof path - 1 ) ;
}
2008-11-11 02:19:13 +03:00
/*
* Print string specified by address ` addr ' and length ` len ' .
* If ` len ' < 0 , treat the string as a NUL - terminated string .
* If string length exceeds ` max_strlen ' , append ` . . . ' to the output .
*/
2007-10-09 01:48:01 +04:00
void
printstr ( struct tcb * tcp , long addr , int len )
1999-02-19 03:21:36 +03:00
{
2007-10-09 01:48:01 +04:00
static char * str = NULL ;
1999-02-19 03:21:36 +03:00
static char * outstr ;
2007-11-02 02:53:59 +03:00
int size ;
1999-02-19 03:21:36 +03:00
if ( ! addr ) {
tprintf ( " NULL " ) ;
return ;
}
2008-11-11 02:19:13 +03:00
/* Allocate static buffers if they are not allocated yet. */
if ( ! str )
str = malloc ( max_strlen + 1 ) ;
if ( ! outstr )
outstr = malloc ( 4 * max_strlen + sizeof " \" ... \" " ) ;
if ( ! str | | ! outstr ) {
fprintf ( stderr , " out of memory \n " ) ;
tprintf ( " %#lx " , addr ) ;
return ;
1999-02-19 03:21:36 +03:00
}
2007-10-09 01:48:01 +04:00
1999-02-19 03:21:36 +03:00
if ( len < 0 ) {
2008-11-11 02:19:13 +03:00
/*
* Treat as a NUL - terminated string : fetch one byte more
* because string_quote ( ) quotes one byte less .
*/
2007-10-09 01:48:01 +04:00
size = max_strlen + 1 ;
2008-11-11 02:19:13 +03:00
str [ max_strlen ] = ' \0 ' ;
2007-10-09 01:48:01 +04:00
if ( umovestr ( tcp , addr , size , str ) < 0 ) {
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , addr ) ;
return ;
}
}
else {
2008-11-11 02:19:13 +03:00
size = MIN ( len , max_strlen ) ;
2007-10-09 01:48:01 +04:00
if ( umoven ( tcp , addr , size , str ) < 0 ) {
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , addr ) ;
return ;
}
}
2008-11-11 02:19:13 +03:00
if ( string_quote ( str , outstr , len , size ) & &
( len < 0 | | len > max_strlen ) )
2007-10-09 01:48:01 +04:00
strcat ( outstr , " ... " ) ;
1999-02-19 03:21:36 +03:00
tprintf ( " %s " , outstr ) ;
}
2001-07-10 17:48:44 +04:00
# if HAVE_SYS_UIO_H
void
dumpiov ( tcp , len , addr )
struct tcb * tcp ;
int len ;
long addr ;
{
2006-12-13 20:08:08 +03:00
# if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
union {
struct { u_int32_t base ; u_int32_t len ; } * iov32 ;
struct { u_int64_t base ; u_int64_t len ; } * iov64 ;
} iovu ;
# define iov iovu.iov64
# define sizeof_iov \
( personality_wordsize [ current_personality ] = = 4 \
? sizeof ( * iovu . iov32 ) : sizeof ( * iovu . iov64 ) )
# define iov_iov_base(i) \
( personality_wordsize [ current_personality ] = = 4 \
? ( u_int64_t ) iovu . iov32 [ i ] . base : iovu . iov64 [ i ] . base )
# define iov_iov_len(i) \
( personality_wordsize [ current_personality ] = = 4 \
? ( u_int64_t ) iovu . iov32 [ i ] . len : iovu . iov64 [ i ] . len )
# else
2001-07-10 17:48:44 +04:00
struct iovec * iov ;
2006-12-13 20:08:08 +03:00
# define sizeof_iov sizeof(*iov)
# define iov_iov_base(i) iov[i].iov_base
# define iov_iov_len(i) iov[i].iov_len
# endif
2001-07-10 17:48:44 +04:00
int i ;
2005-06-01 23:22:06 +04:00
unsigned long size ;
2001-07-10 17:48:44 +04:00
2006-12-13 20:08:08 +03:00
size = sizeof_iov * ( unsigned long ) len ;
if ( size / sizeof_iov ! = len
| | ( iov = malloc ( size ) ) = = NULL ) {
2005-06-01 23:22:06 +04:00
fprintf ( stderr , " out of memory \n " ) ;
2001-07-10 17:48:44 +04:00
return ;
}
2005-06-01 23:22:06 +04:00
if ( umoven ( tcp , addr , size , ( char * ) iov ) > = 0 ) {
2001-07-10 17:48:44 +04:00
for ( i = 0 ; i < len ; i + + ) {
/* include the buffer number to make it easy to
* match up the trace with the source */
tprintf ( " * %lu bytes in buffer %d \n " ,
2006-12-13 20:08:08 +03:00
( unsigned long ) iov_iov_len ( i ) , i ) ;
dumpstr ( tcp , ( long ) iov_iov_base ( i ) ,
iov_iov_len ( i ) ) ;
2001-07-10 17:48:44 +04:00
}
}
free ( ( char * ) iov ) ;
2006-12-13 20:08:08 +03:00
# undef sizeof_iov
# undef iov_iov_base
# undef iov_iov_len
# undef iov
2001-07-10 17:48:44 +04:00
}
# endif
1999-02-19 03:21:36 +03:00
void
dumpstr ( tcp , addr , len )
struct tcb * tcp ;
long addr ;
int len ;
{
static int strsize = - 1 ;
static unsigned char * str ;
static char outstr [ 80 ] ;
char * s ;
int i , j ;
if ( strsize < len ) {
if ( str )
free ( str ) ;
if ( ( str = malloc ( len ) ) = = NULL ) {
2005-06-01 22:55:42 +04:00
fprintf ( stderr , " out of memory \n " ) ;
1999-02-19 03:21:36 +03:00
return ;
}
strsize = len ;
}
if ( umoven ( tcp , addr , len , ( char * ) str ) < 0 )
return ;
for ( i = 0 ; i < len ; i + = 16 ) {
s = outstr ;
sprintf ( s , " | %05x " , i ) ;
s + = 9 ;
for ( j = 0 ; j < 16 ; j + + ) {
if ( j = = 8 )
* s + + = ' ' ;
if ( i + j < len ) {
sprintf ( s , " %02x " , str [ i + j ] ) ;
s + = 3 ;
}
else {
* s + + = ' ' ; * s + + = ' ' ; * s + + = ' ' ;
}
}
* s + + = ' ' ; * s + + = ' ' ;
for ( j = 0 ; j < 16 ; j + + ) {
if ( j = = 8 )
* s + + = ' ' ;
if ( i + j < len ) {
if ( isprint ( str [ i + j ] ) )
* s + + = str [ i + j ] ;
else
* s + + = ' . ' ;
}
else
* s + + = ' ' ;
}
tprintf ( " %s | \n " , outstr ) ;
}
}
# define PAGMASK (~(PAGSIZ - 1))
/*
* move ` len ' bytes of data from process ` pid '
* at address ` addr ' to our space at ` laddr '
*/
int
umoven ( tcp , addr , len , laddr )
struct tcb * tcp ;
long addr ;
int len ;
char * laddr ;
{
# ifdef LINUX
int pid = tcp - > pid ;
int n , m ;
1999-03-15 22:49:42 +03:00
int started = 0 ;
1999-02-19 03:21:36 +03:00
union {
long val ;
char x [ sizeof ( long ) ] ;
} u ;
if ( addr & ( sizeof ( long ) - 1 ) ) {
/* addr not a multiple of sizeof(long) */
n = addr - ( addr & - sizeof ( long ) ) ; /* residue */
addr & = - sizeof ( long ) ; /* residue */
errno = 0 ;
u . val = ptrace ( PTRACE_PEEKDATA , pid , ( char * ) addr , 0 ) ;
if ( errno ) {
1999-03-15 22:49:42 +03:00
if ( started & & ( errno = = EPERM | | errno = = EIO ) ) {
1999-02-19 03:21:36 +03:00
/* Ran into 'end of memory' - stupid "printpath" */
return 0 ;
}
1999-03-15 22:49:42 +03:00
/* But if not started, we had a bogus address. */
2007-08-02 06:22:06 +04:00
if ( addr ! = 0 & & errno ! = EIO )
perror ( " ptrace: umoven " ) ;
1999-02-19 03:21:36 +03:00
return - 1 ;
}
1999-03-15 22:49:42 +03:00
started = 1 ;
1999-02-19 03:21:36 +03:00
memcpy ( laddr , & u . x [ n ] , m = MIN ( sizeof ( long ) - n , len ) ) ;
addr + = sizeof ( long ) , laddr + = m , len - = m ;
}
while ( len ) {
errno = 0 ;
u . val = ptrace ( PTRACE_PEEKDATA , pid , ( char * ) addr , 0 ) ;
if ( errno ) {
1999-03-15 22:49:42 +03:00
if ( started & & ( errno = = EPERM | | errno = = EIO ) ) {
1999-02-19 03:21:36 +03:00
/* Ran into 'end of memory' - stupid "printpath" */
return 0 ;
}
2007-08-02 06:22:06 +04:00
if ( addr ! = 0 & & errno ! = EIO )
2003-01-30 23:15:19 +03:00
perror ( " ptrace: umoven " ) ;
1999-02-19 03:21:36 +03:00
return - 1 ;
}
1999-03-15 22:49:42 +03:00
started = 1 ;
1999-02-19 03:21:36 +03:00
memcpy ( laddr , u . x , m = MIN ( sizeof ( long ) , len ) ) ;
addr + = sizeof ( long ) , laddr + = m , len - = m ;
}
# endif /* LINUX */
# ifdef SUNOS4
int pid = tcp - > pid ;
#if 0
int n , m ;
union {
long val ;
char x [ sizeof ( long ) ] ;
} u ;
if ( addr & ( sizeof ( long ) - 1 ) ) {
/* addr not a multiple of sizeof(long) */
n = addr - ( addr & - sizeof ( long ) ) ; /* residue */
addr & = - sizeof ( long ) ; /* residue */
errno = 0 ;
u . val = ptrace ( PTRACE_PEEKDATA , pid , ( char * ) addr , 0 ) ;
if ( errno ) {
perror ( " umoven " ) ;
return - 1 ;
}
memcpy ( laddr , & u . x [ n ] , m = MIN ( sizeof ( long ) - n , len ) ) ;
addr + = sizeof ( long ) , laddr + = m , len - = m ;
}
while ( len ) {
errno = 0 ;
u . val = ptrace ( PTRACE_PEEKDATA , pid , ( char * ) addr , 0 ) ;
if ( errno ) {
perror ( " umoven " ) ;
return - 1 ;
}
memcpy ( laddr , u . x , m = MIN ( sizeof ( long ) , len ) ) ;
addr + = sizeof ( long ) , laddr + = m , len - = m ;
}
# else /* !oldway */
int n ;
while ( len ) {
n = MIN ( len , PAGSIZ ) ;
n = MIN ( n , ( ( addr + PAGSIZ ) & PAGMASK ) - addr ) ;
if ( ptrace ( PTRACE_READDATA , pid ,
( char * ) addr , len , laddr ) < 0 ) {
perror ( " umoven: ptrace(PTRACE_READDATA, ...) " ) ;
abort ( ) ;
return - 1 ;
}
len - = n ;
addr + = n ;
laddr + = n ;
}
# endif /* !oldway */
# endif /* SUNOS4 */
2000-09-02 01:03:06 +04:00
# ifdef USE_PROCFS
1999-11-29 18:34:02 +03:00
# ifdef HAVE_MP_PROCFS
2001-05-15 18:53:43 +04:00
int fd = tcp - > pfd_as ;
1999-08-30 03:15:07 +04:00
# else
2001-05-15 18:53:43 +04:00
int fd = tcp - > pfd ;
1999-02-19 03:21:36 +03:00
# endif
2001-05-15 18:53:43 +04:00
lseek ( fd , addr , SEEK_SET ) ;
if ( read ( fd , laddr , len ) = = - 1 )
1999-02-19 03:21:36 +03:00
return - 1 ;
2000-09-02 01:03:06 +04:00
# endif /* USE_PROCFS */
1999-02-19 03:21:36 +03:00
return 0 ;
}
/*
* like ` umove ' but make the additional effort of looking
* for a terminating zero byte .
*/
int
umovestr ( tcp , addr , len , laddr )
struct tcb * tcp ;
long addr ;
int len ;
char * laddr ;
{
2000-09-02 01:03:06 +04:00
# ifdef USE_PROCFS
2001-05-15 18:53:43 +04:00
# ifdef HAVE_MP_PROCFS
int fd = tcp - > pfd_as ;
# else
int fd = tcp - > pfd ;
# endif
/* Some systems (e.g. FreeBSD) can be upset if we read off the
end of valid memory , avoid this by trying to read up
to page boundaries . But we don ' t know what a page is ( and
getpagesize ( 2 ) ( if it exists ) doesn ' t necessarily return
hardware page size ) . Assume all pages > = 1024 ( a - historical
I know ) */
int page = 1024 ; /* How to find this? */
int move = page - ( addr & ( page - 1 ) ) ;
int left = len ;
lseek ( fd , addr , SEEK_SET ) ;
while ( left ) {
if ( move > left ) move = left ;
2001-10-16 14:20:22 +04:00
if ( ( move = read ( fd , laddr , move ) ) < = 0 )
2001-05-15 18:53:43 +04:00
return left ! = len ? 0 : - 1 ;
if ( memchr ( laddr , 0 , move ) ) break ;
left - = move ;
laddr + = move ;
addr + = move ;
move = page ;
}
2000-09-02 01:03:06 +04:00
# else /* !USE_PROCFS */
1999-03-15 22:49:42 +03:00
int started = 0 ;
1999-02-19 03:21:36 +03:00
int pid = tcp - > pid ;
int i , n , m ;
union {
long val ;
char x [ sizeof ( long ) ] ;
} u ;
if ( addr & ( sizeof ( long ) - 1 ) ) {
/* addr not a multiple of sizeof(long) */
n = addr - ( addr & - sizeof ( long ) ) ; /* residue */
addr & = - sizeof ( long ) ; /* residue */
errno = 0 ;
u . val = ptrace ( PTRACE_PEEKDATA , pid , ( char * ) addr , 0 ) ;
if ( errno ) {
1999-03-15 22:49:42 +03:00
if ( started & & ( errno = = EPERM | | errno = = EIO ) ) {
1999-02-19 03:21:36 +03:00
/* Ran into 'end of memory' - stupid "printpath" */
return 0 ;
}
2007-08-02 06:22:06 +04:00
if ( addr ! = 0 & & errno ! = EIO )
perror ( " umovestr " ) ;
1999-02-19 03:21:36 +03:00
return - 1 ;
}
1999-03-15 22:49:42 +03:00
started = 1 ;
1999-02-19 03:21:36 +03:00
memcpy ( laddr , & u . x [ n ] , m = MIN ( sizeof ( long ) - n , len ) ) ;
while ( n & ( sizeof ( long ) - 1 ) )
if ( u . x [ n + + ] = = ' \0 ' )
return 0 ;
addr + = sizeof ( long ) , laddr + = m , len - = m ;
}
while ( len ) {
errno = 0 ;
u . val = ptrace ( PTRACE_PEEKDATA , pid , ( char * ) addr , 0 ) ;
if ( errno ) {
1999-03-15 22:49:42 +03:00
if ( started & & ( errno = = EPERM | | errno = = EIO ) ) {
1999-02-19 03:21:36 +03:00
/* Ran into 'end of memory' - stupid "printpath" */
return 0 ;
}
2007-08-02 06:22:06 +04:00
if ( addr ! = 0 & & errno ! = EIO )
perror ( " umovestr " ) ;
1999-02-19 03:21:36 +03:00
return - 1 ;
}
1999-03-15 22:49:42 +03:00
started = 1 ;
1999-02-19 03:21:36 +03:00
memcpy ( laddr , u . x , m = MIN ( sizeof ( long ) , len ) ) ;
for ( i = 0 ; i < sizeof ( long ) ; i + + )
if ( u . x [ i ] = = ' \0 ' )
return 0 ;
addr + = sizeof ( long ) , laddr + = m , len - = m ;
}
2000-09-02 01:03:06 +04:00
# endif /* !USE_PROCFS */
2001-05-15 18:53:43 +04:00
return 0 ;
1999-02-19 03:21:36 +03:00
}
# ifdef LINUX
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# if !defined (SPARC) && !defined(SPARC64)
1999-02-19 03:21:36 +03:00
# define PTRACE_WRITETEXT 101
# define PTRACE_WRITEDATA 102
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# endif /* !SPARC && !SPARC64 */
1999-02-19 03:21:36 +03:00
# endif /* LINUX */
# ifdef SUNOS4
static int
uload ( cmd , pid , addr , len , laddr )
int cmd ;
int pid ;
long addr ;
int len ;
char * laddr ;
{
#if 0
int n ;
while ( len ) {
n = MIN ( len , PAGSIZ ) ;
n = MIN ( n , ( ( addr + PAGSIZ ) & PAGMASK ) - addr ) ;
if ( ptrace ( cmd , pid , ( char * ) addr , n , laddr ) < 0 ) {
perror ( " uload: ptrace(PTRACE_WRITE, ...) " ) ;
return - 1 ;
}
len - = n ;
addr + = n ;
laddr + = n ;
}
# else
int peek , poke ;
int n , m ;
union {
long val ;
char x [ sizeof ( long ) ] ;
} u ;
if ( cmd = = PTRACE_WRITETEXT ) {
peek = PTRACE_PEEKTEXT ;
poke = PTRACE_POKETEXT ;
}
else {
peek = PTRACE_PEEKDATA ;
poke = PTRACE_POKEDATA ;
}
if ( addr & ( sizeof ( long ) - 1 ) ) {
/* addr not a multiple of sizeof(long) */
n = addr - ( addr & - sizeof ( long ) ) ; /* residue */
addr & = - sizeof ( long ) ;
errno = 0 ;
u . val = ptrace ( peek , pid , ( char * ) addr , 0 ) ;
if ( errno ) {
perror ( " uload: POKE " ) ;
return - 1 ;
}
memcpy ( & u . x [ n ] , laddr , m = MIN ( sizeof ( long ) - n , len ) ) ;
if ( ptrace ( poke , pid , ( char * ) addr , u . val ) < 0 ) {
perror ( " uload: POKE " ) ;
return - 1 ;
}
addr + = sizeof ( long ) , laddr + = m , len - = m ;
}
while ( len ) {
if ( len < sizeof ( long ) )
u . val = ptrace ( peek , pid , ( char * ) addr , 0 ) ;
memcpy ( u . x , laddr , m = MIN ( sizeof ( long ) , len ) ) ;
if ( ptrace ( poke , pid , ( char * ) addr , u . val ) < 0 ) {
perror ( " uload: POKE " ) ;
return - 1 ;
}
addr + = sizeof ( long ) , laddr + = m , len - = m ;
}
# endif
return 0 ;
}
int
tload ( pid , addr , len , laddr )
int pid ;
int addr , len ;
char * laddr ;
{
return uload ( PTRACE_WRITETEXT , pid , addr , len , laddr ) ;
}
int
dload ( pid , addr , len , laddr )
int pid ;
int addr ;
int len ;
char * laddr ;
{
return uload ( PTRACE_WRITEDATA , pid , addr , len , laddr ) ;
}
# endif /* SUNOS4 */
2000-09-02 01:03:06 +04:00
# ifndef USE_PROCFS
1999-02-19 03:21:36 +03:00
int
2008-12-16 21:18:40 +03:00
upeek ( tcp , off , res )
struct tcb * tcp ;
1999-02-19 03:21:36 +03:00
long off ;
long * res ;
{
long val ;
# ifdef SUNOS4_KERNEL_ARCH_KLUDGE
{
static int is_sun4m = - 1 ;
struct utsname name ;
/* Round up the usual suspects. */
if ( is_sun4m = = - 1 ) {
if ( uname ( & name ) < 0 ) {
perror ( " upeek: uname? " ) ;
exit ( 1 ) ;
}
is_sun4m = strcmp ( name . machine , " sun4m " ) = = 0 ;
if ( is_sun4m ) {
2004-09-04 07:39:20 +04:00
extern const struct xlat struct_user_offsets [ ] ;
const struct xlat * x ;
1999-02-19 03:21:36 +03:00
for ( x = struct_user_offsets ; x - > str ; x + + )
x - > val + = 1024 ;
}
}
if ( is_sun4m )
off + = 1024 ;
}
# endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
errno = 0 ;
2008-12-17 22:21:59 +03:00
val = do_ptrace ( PTRACE_PEEKUSER , tcp , ( char * ) off , 0 ) ;
1999-02-19 03:21:36 +03:00
if ( val = = - 1 & & errno ) {
2008-12-17 22:21:59 +03:00
if ( errno ! = ESRCH ) {
char buf [ 60 ] ;
sprintf ( buf , " upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0) " , tcp - > pid , off ) ;
perror ( buf ) ;
}
1999-02-19 03:21:36 +03:00
return - 1 ;
}
* res = val ;
return 0 ;
}
2000-09-02 01:03:06 +04:00
# endif /* !USE_PROCFS */
1999-02-19 03:21:36 +03:00
2005-06-09 00:45:28 +04:00
#if 0
1999-02-19 03:21:36 +03:00
long
getpc ( tcp )
struct tcb * tcp ;
{
# ifdef LINUX
long pc ;
1999-11-01 00:15:38 +03:00
# if defined(I386)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * EIP , & pc ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
2002-09-23 19:41:01 +04:00
# elif defined(X86_64)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 8 * RIP , & pc ) < 0 )
2002-09-23 19:41:01 +04:00
return - 1 ;
2000-02-04 00:58:30 +03:00
# elif defined(IA64)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_B0 , & pc ) < 0 )
2000-02-04 00:58:30 +03:00
return - 1 ;
1999-11-01 00:15:38 +03:00
# elif defined(ARM)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * 15 , & pc ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
2008-11-11 01:21:41 +03:00
# elif defined(BFIN)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_PC , & pc ) < 0 )
2008-11-11 01:21:41 +03:00
return - 1 ;
1999-11-01 00:15:38 +03:00
# elif defined(POWERPC)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , sizeof ( unsigned long ) * PT_NIP , & pc ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
2005-06-08 22:06:22 +04:00
# elif defined(M68K)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * PT_PC , & pc ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
1999-11-01 00:15:38 +03:00
# elif defined(ALPHA)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_PC , & pc ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
1999-11-01 00:15:38 +03:00
# elif defined(MIPS)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_EPC , & pc ) < 0 )
1999-11-01 00:15:38 +03:00
return - 1 ;
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# elif defined(SPARC) || defined(SPARC64)
1999-08-30 03:15:07 +04:00
struct regs regs ;
1999-02-19 03:21:36 +03:00
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 )
return - 1 ;
1999-08-30 03:15:07 +04:00
pc = regs . r_pc ;
2002-10-07 18:31:00 +04:00
# elif defined(S390) || defined(S390X)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_PSWADDR , & pc ) < 0 )
2002-10-07 18:31:00 +04:00
return - 1 ;
2001-03-27 16:17:16 +04:00
# elif defined(HPPA)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_IAOQ0 , & pc ) < 0 )
2001-03-27 16:17:16 +04:00
return - 1 ;
2002-05-01 20:39:22 +04:00
# elif defined(SH)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * REG_PC , & pc ) < 0 )
2002-05-01 20:39:22 +04:00
return - 1 ;
2003-06-27 02:40:42 +04:00
# elif defined(SH64)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_PC , & pc ) < 0 )
2003-06-02 23:18:58 +04:00
return - 1 ;
1999-12-23 18:08:17 +03:00
# endif
1999-02-19 03:21:36 +03:00
return pc ;
# endif /* LINUX */
# ifdef SUNOS4
/*
* Return current program counter for ` pid '
* Assumes PC is never 0xffffffff
*/
struct regs regs ;
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " getpc: ptrace(PTRACE_GETREGS, ...) " ) ;
return - 1 ;
}
return regs . r_pc ;
# endif /* SUNOS4 */
# ifdef SVR4
/* XXX */
return 0 ;
# endif /* SVR4 */
2000-09-02 01:03:06 +04:00
# ifdef FREEBSD
struct reg regs ;
pread ( tcp - > pfd_reg , & regs , sizeof ( regs ) , 0 ) ;
return regs . r_eip ;
# endif /* FREEBSD */
1999-02-19 03:21:36 +03:00
}
2005-06-09 00:45:28 +04:00
# endif
1999-02-19 03:21:36 +03:00
void
printcall ( tcp )
struct tcb * tcp ;
{
2005-02-02 23:55:23 +03:00
# define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
sizeof ( long ) = = 8 ? " [????????????????] " : \
NULL /* crash */ )
1999-02-19 03:21:36 +03:00
# ifdef LINUX
# ifdef I386
long eip ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * EIP , & eip ) < 0 ) {
2005-02-02 23:55:23 +03:00
PRINTBADPC ;
1999-02-19 03:21:36 +03:00
return ;
}
tprintf ( " [%08lx] " , eip ) ;
2005-02-02 05:48:53 +03:00
# elif defined(S390) || defined(S390X)
long psw ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_PSWADDR , & psw ) < 0 ) {
2005-02-02 23:55:23 +03:00
PRINTBADPC ;
2005-02-02 05:48:53 +03:00
return ;
}
# ifdef S390
tprintf ( " [%08lx] " , psw ) ;
# elif S390X
tprintf ( " [%16lx] " , psw ) ;
# endif
2002-09-23 19:41:01 +04:00
# elif defined(X86_64)
long rip ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 8 * RIP , & rip ) < 0 ) {
2005-02-02 23:55:23 +03:00
PRINTBADPC ;
2002-09-23 19:41:01 +04:00
return ;
}
tprintf ( " [%16lx] " , rip ) ;
2003-06-04 03:28:59 +04:00
# elif defined(IA64)
2000-02-04 00:58:30 +03:00
long ip ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_B0 , & ip ) < 0 ) {
2005-02-02 23:55:23 +03:00
PRINTBADPC ;
2000-02-04 00:58:30 +03:00
return ;
}
tprintf ( " [%08lx] " , ip ) ;
2000-02-20 02:59:03 +03:00
# elif defined(POWERPC)
1999-02-19 03:21:36 +03:00
long pc ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , sizeof ( unsigned long ) * PT_NIP , & pc ) < 0 ) {
1999-02-19 03:21:36 +03:00
tprintf ( " [????????] " ) ;
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2005-06-08 22:06:22 +04:00
# elif defined(M68K)
1999-02-19 03:21:36 +03:00
long pc ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * PT_PC , & pc ) < 0 ) {
1999-02-19 03:21:36 +03:00
tprintf ( " [????????] " ) ;
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2000-02-20 02:59:03 +03:00
# elif defined(ALPHA)
1999-02-19 03:21:36 +03:00
long pc ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_PC , & pc ) < 0 ) {
2005-02-02 23:55:23 +03:00
tprintf ( " [????????????????] " ) ;
1999-02-19 03:21:36 +03:00
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# elif defined(SPARC) || defined(SPARC64)
1999-08-30 03:15:07 +04:00
struct regs regs ;
1999-02-19 03:21:36 +03:00
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
2005-02-02 23:55:23 +03:00
PRINTBADPC ;
1999-02-19 03:21:36 +03:00
return ;
}
1999-08-30 03:15:07 +04:00
tprintf ( " [%08lx] " , regs . r_pc ) ;
2001-03-27 16:17:16 +04:00
# elif defined(HPPA)
long pc ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_IAOQ0 , & pc ) < 0 ) {
2001-03-27 16:17:16 +04:00
tprintf ( " [????????] " ) ;
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2001-04-10 14:22:50 +04:00
# elif defined(MIPS)
long pc ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_EPC , & pc ) < 0 ) {
2001-04-10 14:22:50 +04:00
tprintf ( " [????????] " ) ;
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2002-05-01 20:39:22 +04:00
# elif defined(SH)
long pc ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * REG_PC , & pc ) < 0 ) {
2002-05-01 20:39:22 +04:00
tprintf ( " [????????] " ) ;
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2003-06-27 02:40:42 +04:00
# elif defined(SH64)
2003-06-02 23:18:58 +04:00
long pc ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_PC , & pc ) < 0 ) {
2005-02-02 23:55:23 +03:00
tprintf ( " [????????????????] " ) ;
2003-06-02 23:18:58 +04:00
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2003-06-04 03:28:59 +04:00
# elif defined(ARM)
long pc ;
2003-06-02 23:18:58 +04:00
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * 15 , & pc ) < 0 ) {
2005-02-02 23:55:23 +03:00
PRINTBADPC ;
2003-06-04 03:28:59 +04:00
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2008-11-11 01:21:41 +03:00
# elif defined(BFIN)
long pc ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_PC , & pc ) < 0 ) {
2008-11-11 01:21:41 +03:00
PRINTBADPC ;
return ;
}
tprintf ( " [%08lx] " , pc ) ;
2000-02-20 02:59:03 +03:00
# endif /* !architecture */
1999-02-19 03:21:36 +03:00
# endif /* LINUX */
# ifdef SUNOS4
struct regs regs ;
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " printcall: ptrace(PTRACE_GETREGS, ...) " ) ;
2005-02-02 23:55:23 +03:00
PRINTBADPC ;
1999-02-19 03:21:36 +03:00
return ;
}
tprintf ( " [%08x] " , regs . r_o7 ) ;
# endif /* SUNOS4 */
# ifdef SVR4
/* XXX */
2005-02-02 23:55:23 +03:00
PRINTBADPC ;
1999-02-19 03:21:36 +03:00
# endif
2000-09-02 01:03:06 +04:00
# ifdef FREEBSD
struct reg regs ;
pread ( tcp - > pfd_reg , & regs , sizeof ( regs ) , 0 ) ;
tprintf ( " [%08x] " , regs . r_eip ) ;
# endif /* FREEBSD */
1999-02-19 03:21:36 +03:00
}
2000-09-02 01:03:06 +04:00
# ifndef USE_PROCFS
1999-02-19 03:21:36 +03:00
2003-01-09 09:53:34 +03:00
# if defined LINUX
2008-05-20 04:34:34 +04:00
# include "syscall.h"
2003-01-09 09:53:34 +03:00
# include <sys/syscall.h>
# ifndef CLONE_PTRACE
# define CLONE_PTRACE 0x00002000
# endif
2008-07-18 05:09:44 +04:00
# ifndef CLONE_VFORK
# define CLONE_VFORK 0x00004000
# endif
2008-08-07 01:43:35 +04:00
# ifndef CLONE_VM
# define CLONE_VM 0x00000100
# endif
2005-06-08 03:21:31 +04:00
# ifndef CLONE_STOPPED
# define CLONE_STOPPED 0x02000000
# endif
2003-01-09 09:53:34 +03:00
# ifdef IA64
2004-02-21 01:56:43 +03:00
/* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
subsystem has them for x86 . . . */
# define SYS_fork 2
# define SYS_vfork 190
2003-01-09 09:53:34 +03:00
typedef unsigned long * arg_setup_state ;
static int
arg_setup ( struct tcb * tcp , arg_setup_state * state )
{
2008-08-07 01:38:52 +04:00
unsigned long cfm , sof , sol ;
long bsp ;
2003-01-09 09:53:34 +03:00
2008-08-07 01:38:52 +04:00
if ( ia32 ) {
/* Satisfy a false GCC warning. */
* state = NULL ;
2004-02-21 01:56:43 +03:00
return 0 ;
2008-08-07 01:38:52 +04:00
}
2004-02-21 01:56:43 +03:00
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_AR_BSP , & bsp ) < 0 )
2003-01-09 09:53:34 +03:00
return - 1 ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_CFM , ( long * ) & cfm ) < 0 )
2003-01-09 09:53:34 +03:00
return - 1 ;
sof = ( cfm > > 0 ) & 0x7f ;
sol = ( cfm > > 7 ) & 0x7f ;
2008-08-07 01:38:52 +04:00
bsp = ( long ) ia64_rse_skip_regs ( ( unsigned long * ) bsp , - sof + sol ) ;
2003-01-09 09:53:34 +03:00
2008-08-07 01:38:52 +04:00
* state = ( unsigned long * ) bsp ;
2003-01-09 09:53:34 +03:00
return 0 ;
}
# define arg_finish_change(tcp, state) 0
# ifdef SYS_fork
static int
get_arg0 ( struct tcb * tcp , arg_setup_state * state , long * valp )
{
2004-02-21 01:56:43 +03:00
int ret ;
if ( ia32 )
2008-12-16 21:18:40 +03:00
ret = upeek ( tcp , PT_R11 , valp ) ;
2004-02-21 01:56:43 +03:00
else
ret = umoven ( tcp ,
( unsigned long ) ia64_rse_skip_regs ( * state , 0 ) ,
sizeof ( long ) , ( void * ) valp ) ;
return ret ;
2003-01-09 09:53:34 +03:00
}
static int
get_arg1 ( struct tcb * tcp , arg_setup_state * state , long * valp )
{
2004-02-21 01:56:43 +03:00
int ret ;
if ( ia32 )
2008-12-16 21:18:40 +03:00
ret = upeek ( tcp , PT_R9 , valp ) ;
2004-02-21 01:56:43 +03:00
else
ret = umoven ( tcp ,
( unsigned long ) ia64_rse_skip_regs ( * state , 1 ) ,
sizeof ( long ) , ( void * ) valp ) ;
return ret ;
2003-01-09 09:53:34 +03:00
}
# endif
static int
set_arg0 ( struct tcb * tcp , arg_setup_state * state , long val )
{
2004-02-21 01:56:43 +03:00
int req = PTRACE_POKEDATA ;
void * ap ;
if ( ia32 ) {
ap = ( void * ) ( intptr_t ) PT_R11 ; /* r11 == EBX */
req = PTRACE_POKEUSER ;
} else
ap = ia64_rse_skip_regs ( * state , 0 ) ;
2003-01-09 09:53:34 +03:00
errno = 0 ;
2004-02-21 01:56:43 +03:00
ptrace ( req , tcp - > pid , ap , val ) ;
2003-01-09 09:53:34 +03:00
return errno ? - 1 : 0 ;
}
static int
set_arg1 ( struct tcb * tcp , arg_setup_state * state , long val )
{
2004-02-21 01:56:43 +03:00
int req = PTRACE_POKEDATA ;
void * ap ;
if ( ia32 ) {
ap = ( void * ) ( intptr_t ) PT_R9 ; /* r9 == ECX */
req = PTRACE_POKEUSER ;
} else
ap = ia64_rse_skip_regs ( * state , 1 ) ;
2003-01-09 09:53:34 +03:00
errno = 0 ;
2004-02-21 01:56:43 +03:00
ptrace ( req , tcp - > pid , ap , val ) ;
2003-01-09 09:53:34 +03:00
return errno ? - 1 : 0 ;
}
2008-07-18 05:19:36 +04:00
/* ia64 does not return the input arguments from functions (and syscalls)
according to ia64 RSE ( Register Stack Engine ) behavior . */
# define restore_arg0(tcp, state, val) ((void) (state), 0)
# define restore_arg1(tcp, state, val) ((void) (state), 0)
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# elif defined (SPARC) || defined (SPARC64)
2003-01-09 09:53:34 +03:00
typedef struct regs arg_setup_state ;
# define arg_setup(tcp, state) \
( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) ( state ) , 0 ) )
# define arg_finish_change(tcp, state) \
( ptrace ( PTRACE_SETREGS , tcp - > pid , ( char * ) ( state ) , 0 ) )
# define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
# define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
# define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
# define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
2003-01-14 12:46:15 +03:00
# define restore_arg0(tcp, state, val) 0
2003-01-09 09:53:34 +03:00
# else
# if defined S390 || defined S390X
2003-01-20 12:04:36 +03:00
/* Note: this is only true for the `clone' system call, which handles
arguments specially . We could as well say that its first two arguments
are swapped relative to other architectures , but that would just be
another # ifdef in the calls . */
# define arg0_offset PT_GPR3
# define arg1_offset PT_ORIGGPR2
# define restore_arg0(tcp, state, val) ((void) (state), 0)
# define restore_arg1(tcp, state, val) ((void) (state), 0)
2004-03-01 23:57:09 +03:00
# define arg0_index 1
# define arg1_index 0
2003-01-09 09:53:34 +03:00
# elif defined (ALPHA) || defined (MIPS)
# define arg0_offset REG_A0
# define arg1_offset (REG_A0+1)
# elif defined (POWERPC)
2003-01-14 12:59:00 +03:00
# define arg0_offset (sizeof(unsigned long)*PT_R3)
# define arg1_offset (sizeof(unsigned long)*PT_R4)
2003-01-20 12:04:36 +03:00
# define restore_arg0(tcp, state, val) ((void) (state), 0)
2003-01-09 09:53:34 +03:00
# elif defined (HPPA)
# define arg0_offset PT_GR26
# define arg1_offset (PT_GR26-4)
2003-01-10 23:51:00 +03:00
# elif defined (X86_64)
# define arg0_offset ((long)(8*(current_personality ? RBX : RDI)))
# define arg1_offset ((long)(8*(current_personality ? RCX : RSI)))
2003-03-31 05:03:33 +04:00
# elif defined (SH)
# define arg0_offset (4*(REG_REG0+4))
# define arg1_offset (4*(REG_REG0+5))
2003-06-27 02:40:42 +04:00
# elif defined (SH64)
2003-06-02 23:18:58 +04:00
/* ABI defines arg0 & 1 in r2 & r3 */
# define arg0_offset (REG_OFFSET+16)
# define arg1_offset (REG_OFFSET+24)
# define restore_arg0(tcp, state, val) 0
2003-01-09 09:53:34 +03:00
# else
# define arg0_offset 0
# define arg1_offset 4
2003-03-31 05:03:33 +04:00
# if defined ARM
2003-01-14 12:46:15 +03:00
# define restore_arg0(tcp, state, val) 0
# endif
2003-01-09 09:53:34 +03:00
# endif
typedef int arg_setup_state ;
# define arg_setup(tcp, state) (0)
# define arg_finish_change(tcp, state) 0
# define get_arg0(tcp, cookie, valp) \
2008-12-16 21:18:40 +03:00
( upeek ( ( tcp ) , arg0_offset , ( valp ) ) )
2003-01-09 09:53:34 +03:00
# define get_arg1(tcp, cookie, valp) \
2008-12-16 21:18:40 +03:00
( upeek ( ( tcp ) , arg1_offset , ( valp ) ) )
2003-01-09 09:53:34 +03:00
static int
set_arg0 ( struct tcb * tcp , void * cookie , long val )
{
2005-06-08 03:22:08 +04:00
return ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) arg0_offset , val ) ;
2003-01-09 09:53:34 +03:00
}
static int
set_arg1 ( struct tcb * tcp , void * cookie , long val )
{
return ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) arg1_offset , val ) ;
}
# endif
2003-01-14 12:46:15 +03:00
# ifndef restore_arg0
# define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
# endif
# ifndef restore_arg1
# define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
# endif
2003-01-09 09:53:34 +03:00
2004-03-02 00:05:16 +03:00
# ifndef arg0_index
# define arg0_index 0
# define arg1_index 1
# endif
2003-01-09 09:53:34 +03:00
int
setbpt ( tcp )
struct tcb * tcp ;
{
2008-05-20 04:34:34 +04:00
static int clone_scno [ SUPPORTED_PERSONALITIES ] = { SYS_clone } ;
2003-01-09 09:53:34 +03:00
extern int change_syscall ( struct tcb * , int ) ;
arg_setup_state state ;
if ( tcp - > flags & TCB_BPTSET ) {
fprintf ( stderr , " PANIC: TCB already set in pid %u \n " , tcp - > pid ) ;
return - 1 ;
}
2008-05-20 04:34:34 +04:00
/*
* It ' s a silly kludge to initialize this with a search at runtime .
* But it ' s better than maintaining another magic thing in the
* godforsaken tables .
*/
if ( clone_scno [ current_personality ] = = 0 ) {
int i ;
for ( i = 0 ; i < nsyscalls ; + + i )
if ( sysent [ i ] . sys_func = = sys_clone ) {
clone_scno [ current_personality ] = i ;
break ;
}
}
2005-06-08 03:21:31 +04:00
switch ( known_scno ( tcp ) ) {
2003-01-18 03:19:31 +03:00
# ifdef SYS_vfork
case SYS_vfork :
# endif
2003-01-09 09:53:34 +03:00
# ifdef SYS_fork
case SYS_fork :
2003-01-18 03:21:51 +03:00
# endif
# if defined SYS_fork || defined SYS_vfork
2003-01-09 09:53:34 +03:00
if ( arg_setup ( tcp , & state ) < 0
| | get_arg0 ( tcp , & state , & tcp - > inst [ 0 ] ) < 0
| | get_arg1 ( tcp , & state , & tcp - > inst [ 1 ] ) < 0
2008-05-20 04:34:34 +04:00
| | change_syscall ( tcp , clone_scno [ current_personality ] ) < 0
2003-01-09 09:53:34 +03:00
| | set_arg0 ( tcp , & state , CLONE_PTRACE | SIGCHLD ) < 0
| | set_arg1 ( tcp , & state , 0 ) < 0
| | arg_finish_change ( tcp , & state ) < 0 )
return - 1 ;
2004-03-01 23:57:09 +03:00
tcp - > u_arg [ arg0_index ] = CLONE_PTRACE | SIGCHLD ;
tcp - > u_arg [ arg1_index ] = 0 ;
2003-01-09 09:53:34 +03:00
tcp - > flags | = TCB_BPTSET ;
return 0 ;
# endif
case SYS_clone :
# ifdef SYS_clone2
case SYS_clone2 :
# endif
2008-08-07 01:43:35 +04:00
/* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
contrary to x86 SYS_vfork above . Even on x86 we turn the
vfork semantics into plain fork - each application must not
depend on the vfork specifics according to POSIX . We would
hang waiting for the parent resume otherwise . We need to
clear also CLONE_VM but only in the CLONE_VFORK case as
otherwise we would break pthread_create . */
2008-07-18 05:09:44 +04:00
if ( ( arg_setup ( tcp , & state ) < 0
| | set_arg0 ( tcp , & state ,
( tcp - > u_arg [ arg0_index ] | CLONE_PTRACE )
2008-08-07 01:43:35 +04:00
& ~ ( tcp - > u_arg [ arg0_index ] & CLONE_VFORK
? CLONE_VFORK | CLONE_VM : 0 ) ) < 0
2008-07-18 05:09:44 +04:00
| | arg_finish_change ( tcp , & state ) < 0 ) )
return - 1 ;
2003-01-09 09:53:34 +03:00
tcp - > flags | = TCB_BPTSET ;
2004-03-01 23:57:09 +03:00
tcp - > inst [ 0 ] = tcp - > u_arg [ arg0_index ] ;
tcp - > inst [ 1 ] = tcp - > u_arg [ arg1_index ] ;
2003-01-09 09:53:34 +03:00
return 0 ;
default :
fprintf ( stderr , " PANIC: setbpt for syscall %ld on %u??? \n " ,
tcp - > scno , tcp - > pid ) ;
break ;
}
return - 1 ;
}
int
clearbpt ( tcp )
struct tcb * tcp ;
{
arg_setup_state state ;
if ( arg_setup ( tcp , & state ) < 0
2003-01-14 12:46:15 +03:00
| | restore_arg0 ( tcp , & state , tcp - > inst [ 0 ] ) < 0
| | restore_arg1 ( tcp , & state , tcp - > inst [ 1 ] ) < 0
2003-01-09 09:53:34 +03:00
| | arg_finish_change ( tcp , & state ) )
return - 1 ;
tcp - > flags & = ~ TCB_BPTSET ;
return 0 ;
}
# else
1999-02-19 03:21:36 +03:00
int
setbpt ( tcp )
struct tcb * tcp ;
{
# ifdef LINUX
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# if defined (SPARC) || defined (SPARC64)
1999-02-19 03:21:36 +03:00
/* We simply use the SunOS breakpoint code. */
1999-08-30 03:15:07 +04:00
struct regs regs ;
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
unsigned long inst ;
1999-02-19 03:21:36 +03:00
# define LOOPA 0x30800000 /* ba,a 0 */
if ( tcp - > flags & TCB_BPTSET ) {
fprintf ( stderr , " PANIC: TCB already set in pid %u \n " , tcp - > pid ) ;
return - 1 ;
}
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " setbpt: ptrace(PTRACE_GETREGS, ...) " ) ;
return - 1 ;
}
1999-08-30 03:15:07 +04:00
tcp - > baddr = regs . r_o7 + 8 ;
1999-02-19 03:21:36 +03:00
errno = 0 ;
tcp - > inst [ 0 ] = ptrace ( PTRACE_PEEKTEXT , tcp - > pid , ( char * ) tcp - > baddr , 0 ) ;
if ( errno ) {
perror ( " setbpt: ptrace(PTRACE_PEEKTEXT, ...) " ) ;
return - 1 ;
}
/*
* XXX - BRUTAL MODE ON
* We cannot set a real BPT in the child , since it will not be
* traced at the moment it will reach the trap and would probably
* die with a core dump .
* Thus , we are force our way in by taking out two instructions
* and insert an eternal loop instead , in expectance of the SIGSTOP
* generated by out PTRACE_ATTACH .
* Of cause , if we evaporate ourselves in the middle of all this . . .
*/
errno = 0 ;
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
inst = LOOPA ;
# if defined (SPARC64)
inst < < = 32 ;
inst | = ( tcp - > inst [ 0 ] & 0xffffffffUL ) ;
# endif
ptrace ( PTRACE_POKETEXT , tcp - > pid , ( char * ) tcp - > baddr , inst ) ;
1999-02-19 03:21:36 +03:00
if ( errno ) {
perror ( " setbpt: ptrace(PTRACE_POKETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags | = TCB_BPTSET ;
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# else /* !SPARC && !SPARC64 */
2000-02-04 00:58:30 +03:00
# ifdef IA64
2001-10-10 03:47:38 +04:00
if ( ia32 ) {
# define LOOP 0x0000feeb
if ( tcp - > flags & TCB_BPTSET ) {
fprintf ( stderr , " PANIC: bpt already set in pid %u \n " ,
tcp - > pid ) ;
return - 1 ;
}
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_CR_IIP , & tcp - > baddr ) < 0 )
2001-10-10 03:47:38 +04:00
return - 1 ;
if ( debug )
fprintf ( stderr , " [%d] setting bpt at %lx \n " ,
tcp - > pid , tcp - > baddr ) ;
tcp - > inst [ 0 ] = ptrace ( PTRACE_PEEKTEXT , tcp - > pid ,
( char * ) tcp - > baddr , 0 ) ;
if ( errno ) {
perror ( " setbpt: ptrace(PTRACE_PEEKTEXT, ...) " ) ;
return - 1 ;
}
ptrace ( PTRACE_POKETEXT , tcp - > pid , ( char * ) tcp - > baddr , LOOP ) ;
if ( errno ) {
perror ( " setbpt: ptrace(PTRACE_POKETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags | = TCB_BPTSET ;
} else {
/*
* Our strategy here is to replace the bundle that
* contained the clone ( ) syscall with a bundle of the
* form :
*
* { 1 : br 1 b ; br 1 b ; br 1 b }
*
* This ensures that the newly forked child will loop
* endlessly until we ' ve got a chance to attach to it .
*/
2000-02-04 00:58:30 +03:00
# define LOOP0 0x0000100000000017
# define LOOP1 0x4000000000200000
unsigned long addr , ipsr ;
pid_t pid ;
pid = tcp - > pid ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_CR_IPSR , & ipsr ) < 0 )
2000-02-04 00:58:30 +03:00
return - 1 ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_CR_IIP , & addr ) < 0 )
2000-02-04 00:58:30 +03:00
return - 1 ;
2001-10-10 03:47:38 +04:00
/* store "ri" in low two bits */
tcp - > baddr = addr | ( ( ipsr > > 41 ) & 0x3 ) ;
2000-02-04 00:58:30 +03:00
errno = 0 ;
2001-10-10 03:47:38 +04:00
tcp - > inst [ 0 ] = ptrace ( PTRACE_PEEKTEXT , pid , ( char * ) addr + 0 ,
0 ) ;
tcp - > inst [ 1 ] = ptrace ( PTRACE_PEEKTEXT , pid , ( char * ) addr + 8 ,
0 ) ;
2000-02-04 00:58:30 +03:00
if ( errno ) {
perror ( " setbpt: ptrace(PTRACE_PEEKTEXT, ...) " ) ;
return - 1 ;
}
errno = 0 ;
ptrace ( PTRACE_POKETEXT , pid , ( char * ) addr + 0 , LOOP0 ) ;
ptrace ( PTRACE_POKETEXT , pid , ( char * ) addr + 8 , LOOP1 ) ;
if ( errno ) {
perror ( " setbpt: ptrace(PTRACE_POKETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags | = TCB_BPTSET ;
}
# else /* !IA64 */
1999-02-19 03:21:36 +03:00
2002-09-23 19:41:01 +04:00
# if defined (I386) || defined(X86_64)
1999-02-19 03:21:36 +03:00
# define LOOP 0x0000feeb
# elif defined (M68K)
# define LOOP 0x60fe0000
# elif defined (ALPHA)
1999-12-23 17:20:14 +03:00
# define LOOP 0xc3ffffff
1999-02-19 03:21:36 +03:00
# elif defined (POWERPC)
2002-12-16 23:40:54 +03:00
# define LOOP 0x48000000
1999-02-19 03:21:36 +03:00
# elif defined(ARM)
1999-12-25 02:19:31 +03:00
# define LOOP 0xEAFFFFFE
1999-11-01 00:15:38 +03:00
# elif defined(MIPS)
1999-12-23 17:20:14 +03:00
# define LOOP 0x1000ffff
# elif defined(S390)
# define LOOP 0xa7f40000 /* BRC 15,0 */
2002-10-07 18:31:00 +04:00
# elif defined(S390X)
# define LOOP 0xa7f4000000000000UL /* BRC 15,0 */
2001-03-27 16:17:16 +04:00
# elif defined(HPPA)
# define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */
2002-05-01 20:39:22 +04:00
# elif defined(SH)
# ifdef __LITTLE_ENDIAN__
# define LOOP 0x0000affe
# else
# define LOOP 0xfeaf0000
# endif
1999-02-19 03:21:36 +03:00
# else
# error unknown architecture
# endif
if ( tcp - > flags & TCB_BPTSET ) {
fprintf ( stderr , " PANIC: bpt already set in pid %u \n " , tcp - > pid ) ;
return - 1 ;
}
# if defined (I386)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * EIP , & tcp - > baddr ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
2002-09-23 19:41:01 +04:00
# elif defined (X86_64)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 8 * RIP , & tcp - > baddr ) < 0 )
2002-09-23 19:41:01 +04:00
return - 1 ;
1999-02-19 03:21:36 +03:00
# elif defined (M68K)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * PT_PC , & tcp - > baddr ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
# elif defined (ALPHA)
return - 1 ;
# elif defined (ARM)
return - 1 ;
1999-11-01 00:15:38 +03:00
# elif defined (MIPS)
return - 1 ; /* FIXME: I do not know what i do - Flo */
1999-02-19 03:21:36 +03:00
# elif defined (POWERPC)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , sizeof ( unsigned long ) * PT_NIP , & tcp - > baddr ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
2002-10-07 18:31:00 +04:00
# elif defined(S390) || defined(S390X)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_PSWADDR , & tcp - > baddr ) < 0 )
1999-12-23 17:20:14 +03:00
return - 1 ;
2001-03-27 16:17:16 +04:00
# elif defined(HPPA)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_IAOQ0 , & tcp - > baddr ) < 0 )
2001-03-27 16:17:16 +04:00
return - 1 ;
tcp - > baddr & = ~ 0x03 ;
2002-05-01 20:39:22 +04:00
# elif defined(SH)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * REG_PC , & tcp - > baddr ) < 0 )
2002-05-01 20:39:22 +04:00
return - 1 ;
1999-02-19 03:21:36 +03:00
# else
# error unknown architecture
# endif
if ( debug )
fprintf ( stderr , " [%d] setting bpt at %lx \n " , tcp - > pid , tcp - > baddr ) ;
tcp - > inst [ 0 ] = ptrace ( PTRACE_PEEKTEXT , tcp - > pid , ( char * ) tcp - > baddr , 0 ) ;
if ( errno ) {
perror ( " setbpt: ptrace(PTRACE_PEEKTEXT, ...) " ) ;
return - 1 ;
}
ptrace ( PTRACE_POKETEXT , tcp - > pid , ( char * ) tcp - > baddr , LOOP ) ;
if ( errno ) {
perror ( " setbpt: ptrace(PTRACE_POKETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags | = TCB_BPTSET ;
2000-02-04 00:58:30 +03:00
# endif /* !IA64 */
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# endif /* SPARC || SPARC64 */
1999-02-19 03:21:36 +03:00
# endif /* LINUX */
# ifdef SUNOS4
# ifdef SPARC /* This code is slightly sparc specific */
1999-06-22 19:28:30 +04:00
struct regs regs ;
1999-02-19 03:21:36 +03:00
# define BPT 0x91d02001 /* ta 1 */
# define LOOP 0x10800000 /* ba 0 */
# define LOOPA 0x30800000 /* ba,a 0 */
# define NOP 0x01000000
# if LOOPA
static int loopdeloop [ 1 ] = { LOOPA } ;
# else
static int loopdeloop [ 2 ] = { LOOP , NOP } ;
# endif
if ( tcp - > flags & TCB_BPTSET ) {
fprintf ( stderr , " PANIC: TCB already set in pid %u \n " , tcp - > pid ) ;
return - 1 ;
}
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " setbpt: ptrace(PTRACE_GETREGS, ...) " ) ;
return - 1 ;
}
tcp - > baddr = regs . r_o7 + 8 ;
if ( ptrace ( PTRACE_READTEXT , tcp - > pid , ( char * ) tcp - > baddr ,
sizeof tcp - > inst , ( char * ) tcp - > inst ) < 0 ) {
perror ( " setbpt: ptrace(PTRACE_READTEXT, ...) " ) ;
return - 1 ;
}
/*
* XXX - BRUTAL MODE ON
* We cannot set a real BPT in the child , since it will not be
* traced at the moment it will reach the trap and would probably
* die with a core dump .
* Thus , we are force our way in by taking out two instructions
* and insert an eternal loop in stead , in expectance of the SIGSTOP
* generated by out PTRACE_ATTACH .
* Of cause , if we evaporate ourselves in the middle of all this . . .
*/
if ( ptrace ( PTRACE_WRITETEXT , tcp - > pid , ( char * ) tcp - > baddr ,
sizeof loopdeloop , ( char * ) loopdeloop ) < 0 ) {
perror ( " setbpt: ptrace(PTRACE_WRITETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags | = TCB_BPTSET ;
# endif /* SPARC */
# endif /* SUNOS4 */
return 0 ;
}
int
clearbpt ( tcp )
struct tcb * tcp ;
{
# ifdef LINUX
2002-09-23 19:41:01 +04:00
# if defined(I386) || defined(X86_64)
1999-02-19 03:21:36 +03:00
long eip ;
2000-02-20 02:59:03 +03:00
# elif defined(POWERPC)
1999-02-19 03:21:36 +03:00
long pc ;
2000-02-20 02:59:03 +03:00
# elif defined(M68K)
1999-02-19 03:21:36 +03:00
long pc ;
2000-02-20 02:59:03 +03:00
# elif defined(ALPHA)
1999-02-19 03:21:36 +03:00
long pc ;
2001-03-27 16:17:16 +04:00
# elif defined(HPPA)
long iaoq ;
2002-05-01 20:39:22 +04:00
# elif defined(SH)
long pc ;
2000-02-20 02:59:03 +03:00
# endif /* architecture */
1999-02-19 03:21:36 +03:00
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# if defined (SPARC) || defined (SPARC64)
1999-02-19 03:21:36 +03:00
/* Again, we borrow the SunOS breakpoint code. */
if ( ! ( tcp - > flags & TCB_BPTSET ) ) {
fprintf ( stderr , " PANIC: TCB not set in pid %u \n " , tcp - > pid ) ;
return - 1 ;
}
errno = 0 ;
ptrace ( PTRACE_POKETEXT , tcp - > pid , ( char * ) tcp - > baddr , tcp - > inst [ 0 ] ) ;
if ( errno ) {
perror ( " clearbtp: ptrace(PTRACE_POKETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags & = ~ TCB_BPTSET ;
2000-02-20 02:59:03 +03:00
# elif defined(IA64)
2001-10-10 03:47:38 +04:00
if ( ia32 ) {
unsigned long addr ;
if ( debug )
fprintf ( stderr , " [%d] clearing bpt \n " , tcp - > pid ) ;
if ( ! ( tcp - > flags & TCB_BPTSET ) ) {
fprintf ( stderr , " PANIC: TCB not set in pid %u \n " , tcp - > pid ) ;
return - 1 ;
}
errno = 0 ;
ptrace ( PTRACE_POKETEXT , tcp - > pid , ( char * ) tcp - > baddr , tcp - > inst [ 0 ] ) ;
if ( errno ) {
perror ( " clearbtp: ptrace(PTRACE_POKETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags & = ~ TCB_BPTSET ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_CR_IIP , & addr ) < 0 )
2001-10-10 03:47:38 +04:00
return - 1 ;
if ( addr ! = tcp - > baddr ) {
/* The breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr ,
" NOTE: PC not at bpt (pc %#lx baddr %#lx) \n " ,
addr , tcp - > baddr ) ;
return 0 ;
}
} else {
2000-02-04 00:58:30 +03:00
unsigned long addr , ipsr ;
pid_t pid ;
pid = tcp - > pid ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_CR_IPSR , & ipsr ) < 0 )
2000-02-04 00:58:30 +03:00
return - 1 ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_CR_IIP , & addr ) < 0 )
2000-02-04 00:58:30 +03:00
return - 1 ;
/* restore original bundle: */
errno = 0 ;
ptrace ( PTRACE_POKETEXT , pid , ( char * ) addr + 0 , tcp - > inst [ 0 ] ) ;
ptrace ( PTRACE_POKETEXT , pid , ( char * ) addr + 8 , tcp - > inst [ 1 ] ) ;
if ( errno ) {
perror ( " clearbpt: ptrace(PTRACE_POKETEXT, ...) " ) ;
return - 1 ;
}
/* restore original "ri" in ipsr: */
ipsr = ( ipsr & ~ ( 0x3ul < < 41 ) ) | ( ( tcp - > baddr & 0x3 ) < < 41 ) ;
errno = 0 ;
ptrace ( PTRACE_POKEUSER , pid , ( char * ) PT_CR_IPSR , ipsr ) ;
if ( errno ) {
perror ( " clrbpt: ptrace(PTRACE_POKEUSER, ...) " ) ;
return - 1 ;
}
tcp - > flags & = ~ TCB_BPTSET ;
if ( addr ! = ( tcp - > baddr & ~ 0x3 ) ) {
/* the breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr , " NOTE: PC not at bpt (pc %#lx baddr %#lx) \n " ,
addr , tcp - > baddr ) ;
return 0 ;
}
}
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# else /* !IA64 && !SPARC && !SPARC64 */
1999-02-19 03:21:36 +03:00
if ( debug )
fprintf ( stderr , " [%d] clearing bpt \n " , tcp - > pid ) ;
if ( ! ( tcp - > flags & TCB_BPTSET ) ) {
fprintf ( stderr , " PANIC: TCB not set in pid %u \n " , tcp - > pid ) ;
return - 1 ;
}
errno = 0 ;
ptrace ( PTRACE_POKETEXT , tcp - > pid , ( char * ) tcp - > baddr , tcp - > inst [ 0 ] ) ;
if ( errno ) {
perror ( " clearbtp: ptrace(PTRACE_POKETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags & = ~ TCB_BPTSET ;
# ifdef I386
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * EIP , & eip ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
if ( eip ! = tcp - > baddr ) {
/* The breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr ,
" NOTE: PC not at bpt (pc %#lx baddr %#lx) \n " ,
eip , tcp - > baddr ) ;
return 0 ;
}
2002-09-23 19:41:01 +04:00
# elif defined(X86_64)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 8 * RIP , & eip ) < 0 )
2002-09-23 19:41:01 +04:00
return - 1 ;
if ( eip ! = tcp - > baddr ) {
/* The breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr ,
" NOTE: PC not at bpt (pc %#lx baddr %#lx) \n " ,
eip , tcp - > baddr ) ;
return 0 ;
}
2000-04-11 02:22:31 +04:00
# elif defined(POWERPC)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , sizeof ( unsigned long ) * PT_NIP , & pc ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
if ( pc ! = tcp - > baddr ) {
/* The breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr , " NOTE: PC not at bpt (pc %#lx baddr %#lx) \n " ,
pc , tcp - > baddr ) ;
return 0 ;
}
2000-02-20 02:59:03 +03:00
# elif defined(M68K)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * PT_PC , & pc ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
if ( pc ! = tcp - > baddr ) {
/* The breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr , " NOTE: PC not at bpt (pc %#lx baddr %#lx) \n " ,
pc , tcp - > baddr ) ;
return 0 ;
}
2000-02-20 02:59:03 +03:00
# elif defined(ALPHA)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_PC , & pc ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
if ( pc ! = tcp - > baddr ) {
/* The breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr , " NOTE: PC not at bpt (pc %#lx baddr %#lx) \n " ,
pc , tcp - > baddr ) ;
return 0 ;
}
2001-03-27 16:17:16 +04:00
# elif defined(HPPA)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_IAOQ0 , & iaoq ) < 0 )
2001-03-27 16:17:16 +04:00
return - 1 ;
iaoq & = ~ 0x03 ;
if ( iaoq ! = tcp - > baddr & & iaoq ! = tcp - > baddr + 4 ) {
/* The breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr , " NOTE: PC not at bpt (iaoq %#lx baddr %#lx) \n " ,
iaoq , tcp - > baddr ) ;
return 0 ;
}
iaoq = tcp - > baddr | 3 ;
/* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
* safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
* has no significant effect .
*/
ptrace ( PTRACE_POKEUSER , tcp - > pid , ( void * ) PT_IAOQ0 , iaoq ) ;
ptrace ( PTRACE_POKEUSER , tcp - > pid , ( void * ) PT_IAOQ1 , iaoq ) ;
2002-05-01 20:39:22 +04:00
# elif defined(SH)
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * REG_PC , & pc ) < 0 )
2002-05-01 20:39:22 +04:00
return - 1 ;
if ( pc ! = tcp - > baddr ) {
/* The breakpoint has not been reached yet. */
if ( debug )
fprintf ( stderr , " NOTE: PC not at bpt (pc %#lx baddr %#lx) \n " ,
pc , tcp - > baddr ) ;
return 0 ;
}
2000-02-20 02:59:03 +03:00
# endif /* arch */
2004-07-07 David S. Miller <davem@nuts.davemloft.net>
* linux/sparc/syscallent.h: Sync with reality.
* linux/sparc/syscall.h (sys_sendfile64, sys_futex, sys_gettid,
sys_sched_setaffinity, sys_sched_getaffinity, sys_setxattr,
sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr,
sys_fgetxattr, sys_listxattr, sys_llistxattr, sys_flistxattr,
sys_removexattr, sys_lremovexattr, sys_fremovexattr,
sys_remap_file_pages, sys_readahead, sys_tgkill, sys_statfs64,
sys_fstatfs64, sys_clock_settime, sys_clock_gettime,
sys_clock_getres, sys_clock_nanosleep, sys_timer_create,
sys_timer_settime, sys_timer_gettime): New declarations.
* linux/sparc64/dummy2.h, linux/sparc64/syscallent2.h,
linux/sparc64/syscall.h, linux/sparc64/errnoent.h,
linux/sparc64/errnoent1.h, linux/sparc64/errnoent2.h,
linux/sparc64/ioctlent.h, linux/sparc64/ioctlent1.h,
linux/sparc64/ioctlent2.h, linux/sparc64/signalent.h,
linux/sparc64/signalent.h, linux/sparc64/signalent.h,
linux/sparc64/signalent1.h, linux/sparc64/signalent2.h,
linux/sparc64/syscall1.h, linux/sparc64/syscallent.h,
linux/sparc64/syscallent1.h: New files.
* defs.h (LINUXSPARC): Define also when SPARC64.
(LINUX && SPARC64): Set SUPPORTED_PERSONALITIES to 3.
Ignore SIGTRAP after execve by defining TCB_WAITEXECVE.
Define possibly missing __NR_exit_group. Declare getrval2.
* configure.ac (sparc64): New architecture case.
* config.h.in (SPARC64): New define.
* file.c (stat_sparc64): New structure.
(printstat_sparc64): New output routine for that.
(printstat): Call it, if personality is 2.
(printstat64): Likewise.
* util.c: Conditionalize ptrace defines on LINUXSPARC
not LINUX && SPARC.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(_hack_syscall5): Correct trap number when SPARC64.
(PTRACE_WRITE{TEXT,DATA}): Add SPARC64 to ifdef guard.
(getpc): Handle SPARC64 && LINUX.
(printcall): Likewise.
(arg fetching/setting): Use same code for SPARC64 LINUX
as for SPARC.
(setbpt): Handle SPARC64 && LINUX.
(clearbpt): Likewise.
* signal.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(m_siginfo): Use same definition on SPARC64 as SPARC.
(sys_sigreturn): Handle LINUX && SPARC64.
* syscall.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(getscno): Use same static state on SPARC64 as SPARC,
and add SPARC64 handling.
(get_error): Handle LINUX && SPARC64.
(force_result): Likewise.
(syscall_enter): Likewise.
(trace_syscall): Handle sys_socketcall and sys_ipc on SPARC64
just like SPARC.
(getrval2): Handle LINUX && SPARC64.
* process.c: Conditionalize ptrace defines on SPARC and
SPARC64.
(SPARC64 && LINUX): Define r_pc to r_tpc, and PTRACE_FOOREGS
to PTRACE_FOOREGS64 so that more sparc code can be shared
between 64-bit and 32-bit.
(change_syscall): Handle LINUX && SPARC64.
(struct_user_offsets): Ifdef out those which do not exist
on SPARC64.
* net.c (sys_pipe): Handle LINUX && SPARC64.
* ioctl.c: Fix initializer typo for nioctlents2, was
nioctlents1 by accident.
2004-07-12 11:44:08 +04:00
# endif /* !SPARC && !SPARC64 && !IA64 */
1999-02-19 03:21:36 +03:00
# endif /* LINUX */
# ifdef SUNOS4
# ifdef SPARC
# if !LOOPA
1999-06-22 19:28:30 +04:00
struct regs regs ;
1999-02-19 03:21:36 +03:00
# endif
if ( ! ( tcp - > flags & TCB_BPTSET ) ) {
fprintf ( stderr , " PANIC: TCB not set in pid %u \n " , tcp - > pid ) ;
return - 1 ;
}
if ( ptrace ( PTRACE_WRITETEXT , tcp - > pid , ( char * ) tcp - > baddr ,
sizeof tcp - > inst , ( char * ) tcp - > inst ) < 0 ) {
perror ( " clearbtp: ptrace(PTRACE_WRITETEXT, ...) " ) ;
return - 1 ;
}
tcp - > flags & = ~ TCB_BPTSET ;
# if !LOOPA
/*
* Since we don ' t have a single instruction breakpoint , we may have
* to adjust the program counter after removing the our ` breakpoint ' .
*/
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " clearbpt: ptrace(PTRACE_GETREGS, ...) " ) ;
return - 1 ;
}
if ( ( regs . r_pc < tcp - > baddr ) | |
( regs . r_pc > tcp - > baddr + 4 ) ) {
/* The breakpoint has not been reached yet */
if ( debug )
fprintf ( stderr ,
" NOTE: PC not at bpt (pc %#x baddr %#x) \n " ,
regs . r_pc , tcp - > parent - > baddr ) ;
return 0 ;
}
if ( regs . r_pc ! = tcp - > baddr )
if ( debug )
fprintf ( stderr , " NOTE: PC adjusted (%#x -> %#x \n " ,
regs . r_pc , tcp - > baddr ) ;
regs . r_pc = tcp - > baddr ;
if ( ptrace ( PTRACE_SETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " clearbpt: ptrace(PTRACE_SETREGS, ...) " ) ;
return - 1 ;
}
# endif /* LOOPA */
# endif /* SPARC */
# endif /* SUNOS4 */
return 0 ;
}
2003-01-09 09:53:34 +03:00
# endif
2000-09-02 01:03:06 +04:00
# endif /* !USE_PROCFS */
1999-02-19 03:21:36 +03:00
# ifdef SUNOS4
static int
2008-12-16 21:18:40 +03:00
getex ( tcp , hdr )
struct tcb * tcp ;
1999-02-19 03:21:36 +03:00
struct exec * hdr ;
{
int n ;
for ( n = 0 ; n < sizeof * hdr ; n + = 4 ) {
long res ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , uoff ( u_exdata ) + n , & res ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
memcpy ( ( ( char * ) hdr ) + n , & res , 4 ) ;
}
if ( debug ) {
fprintf ( stderr , " [struct exec: magic: %o version %u Mach %o \n " ,
hdr - > a_magic , hdr - > a_toolversion , hdr - > a_machtype ) ;
fprintf ( stderr , " Text %lu Data %lu Bss %lu Syms %lu Entry %#lx] \n " ,
hdr - > a_text , hdr - > a_data , hdr - > a_bss , hdr - > a_syms , hdr - > a_entry ) ;
}
return 0 ;
}
int
fixvfork ( tcp )
struct tcb * tcp ;
{
int pid = tcp - > pid ;
/*
* Change ` vfork ' in a freshly exec ' ed dynamically linked
* executable ' s ( internal ) symbol table to plain old ` fork '
*/
struct exec hdr ;
struct link_dynamic dyn ;
struct link_dynamic_2 ld ;
char * strtab , * cp ;
2008-12-16 21:18:40 +03:00
if ( getex ( tcp , & hdr ) < 0 )
1999-02-19 03:21:36 +03:00
return - 1 ;
if ( ! hdr . a_dynamic )
return - 1 ;
if ( umove ( tcp , ( int ) N_DATADDR ( hdr ) , & dyn ) < 0 ) {
fprintf ( stderr , " Cannot read DYNAMIC \n " ) ;
return - 1 ;
}
if ( umove ( tcp , ( int ) dyn . ld_un . ld_2 , & ld ) < 0 ) {
fprintf ( stderr , " Cannot read link_dynamic_2 \n " ) ;
return - 1 ;
}
if ( ( strtab = malloc ( ( unsigned ) ld . ld_symb_size ) ) = = NULL ) {
2005-06-01 22:55:42 +04:00
fprintf ( stderr , " out of memory \n " ) ;
1999-02-19 03:21:36 +03:00
return - 1 ;
}
if ( umoven ( tcp , ( int ) ld . ld_symbols + ( int ) N_TXTADDR ( hdr ) ,
( int ) ld . ld_symb_size , strtab ) < 0 )
goto err ;
#if 0
for ( cp = strtab ; cp < strtab + ld . ld_symb_size ; ) {
fprintf ( stderr , " [symbol: %s] \n " , cp ) ;
cp + = strlen ( cp ) + 1 ;
}
return 0 ;
# endif
for ( cp = strtab ; cp < strtab + ld . ld_symb_size ; ) {
if ( strcmp ( cp , " _vfork " ) = = 0 ) {
if ( debug )
fprintf ( stderr , " fixvfork: FOUND _vfork \n " ) ;
strcpy ( cp , " _fork " ) ;
break ;
}
cp + = strlen ( cp ) + 1 ;
}
if ( cp < strtab + ld . ld_symb_size )
/*
* Write entire symbol table back to avoid
* memory alignment bugs in ptrace
*/
if ( tload ( pid , ( int ) ld . ld_symbols + ( int ) N_TXTADDR ( hdr ) ,
( int ) ld . ld_symb_size , strtab ) < 0 )
goto err ;
free ( strtab ) ;
return 0 ;
err :
free ( strtab ) ;
return - 1 ;
}
# endif /* SUNOS4 */