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"
2009-04-15 17:22:59 +04:00
# include <stdint.h>
1999-02-19 03:21:36 +03:00
# include <sys/user.h>
# include <fcntl.h>
1999-07-13 19:45:02 +04:00
# ifdef HAVE_SYS_REG_H
# include <sys / reg.h>
2012-02-25 05:38:52 +04:00
# ifndef PTRACE_PEEKUSR
# define PTRACE_PEEKUSR PTRACE_PEEKUSER
# endif
# ifndef PTRACE_POKEUSR
# define PTRACE_POKEUSR PTRACE_POKEUSER
# endif
2000-02-20 02:59:03 +03:00
# elif defined(HAVE_LINUX_PTRACE_H)
2012-02-25 05:38:52 +04:00
# undef PTRACE_SYSCALL
2004-03-02 00:31:02 +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
2012-02-25 05:38:52 +04:00
# include <linux / ptrace.h>
2004-03-02 00:31:02 +03:00
# undef ia64_fpreg
# undef pt_all_user_regs
1999-10-06 17:06:34 +04:00
# endif
1999-07-13 19:45:02 +04:00
2000-02-04 00:58:30 +03:00
# ifdef IA64
# include <asm / ptrace_offsets.h>
2011-08-18 14:48:56 +04:00
# endif
2000-02-04 00:58:30 +03:00
2012-02-25 05:38:52 +04:00
# if defined(SPARC64)
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
# undef PTRACE_GETREGS
# define PTRACE_GETREGS PTRACE_GETREGS64
# undef PTRACE_SETREGS
# define PTRACE_SETREGS PTRACE_SETREGS64
2012-02-25 05:38:52 +04:00
# endif
2003-01-30 23:15:23 +03:00
2012-02-25 05:38:52 +04:00
# if defined(SPARC) || defined(SPARC64) || defined(MIPS)
2007-11-04 03:00:00 +03:00
typedef struct {
struct pt_regs si_regs ;
int si_mask ;
} m_siginfo_t ;
2003-01-30 23:15:23 +03:00
# elif defined HAVE_ASM_SIGCONTEXT_H
2012-02-25 05:38:52 +04:00
# if !defined(IA64) && !defined(X86_64)
# include <asm / sigcontext.h>
# endif /* !IA64 && !X86_64 */
1999-02-19 03:21:36 +03:00
# else /* !HAVE_ASM_SIGCONTEXT_H */
2012-02-25 05:38:52 +04:00
# if defined I386 && !defined HAVE_STRUCT_SIGCONTEXT_STRUCT
1999-02-19 03:21:36 +03:00
struct sigcontext_struct {
unsigned short gs , __gsh ;
unsigned short fs , __fsh ;
unsigned short es , __esh ;
unsigned short ds , __dsh ;
unsigned long edi ;
unsigned long esi ;
unsigned long ebp ;
unsigned long esp ;
unsigned long ebx ;
unsigned long edx ;
unsigned long ecx ;
unsigned long eax ;
unsigned long trapno ;
unsigned long err ;
unsigned long eip ;
unsigned short cs , __csh ;
unsigned long eflags ;
unsigned long esp_at_signal ;
unsigned short ss , __ssh ;
unsigned long i387 ;
unsigned long oldmask ;
unsigned long cr2 ;
} ;
2012-02-25 05:38:52 +04:00
# else /* !I386 */
# if defined M68K && !defined HAVE_STRUCT_SIGCONTEXT
1999-05-09 04:29:58 +04:00
struct sigcontext
1999-02-19 03:21:36 +03:00
{
unsigned long sc_mask ;
unsigned long sc_usp ;
unsigned long sc_d0 ;
unsigned long sc_d1 ;
unsigned long sc_a0 ;
unsigned long sc_a1 ;
unsigned short sc_sr ;
unsigned long sc_pc ;
unsigned short sc_formatvec ;
} ;
2012-02-25 05:38:52 +04:00
# endif /* M68K */
# endif /* !I386 */
1999-02-19 03:21:36 +03:00
# endif /* !HAVE_ASM_SIGCONTEXT_H */
2011-08-18 14:48:56 +04:00
1999-02-19 03:21:36 +03:00
# ifndef NSIG
2012-02-25 05:38:52 +04:00
# warning: NSIG is not defined, using 32
# define NSIG 32
1999-02-19 03:21:36 +03:00
# endif
# ifdef ARM
2011-08-18 14:48:56 +04:00
/* Ugh. Is this really correct? ARM has no RT signals?! */
2012-02-25 05:38:52 +04:00
# undef NSIG
# define NSIG 32
1999-02-19 03:21:36 +03:00
# endif
2011-08-18 14:48:56 +04:00
1999-02-19 03:21:36 +03:00
# ifdef HAVE_SIGACTION
2012-02-25 18:19:02 +04:00
# if defined(I386) || defined(X86_64)
2002-12-16 02:58:41 +03:00
/* The libc headers do not define this constant since it should only be
2011-08-18 14:48:56 +04:00
used by the implementation . So we define it here . */
2002-12-16 02:58:41 +03:00
# ifndef SA_RESTORER
# define SA_RESTORER 0x04000000
# endif
# endif
2004-09-04 07:39:20 +04:00
static const struct xlat sigact_flags [ ] = {
2000-04-11 02:22:31 +04:00
# ifdef SA_RESTORER
{ SA_RESTORER , " SA_RESTORER " } ,
# endif
1999-02-19 03:21:36 +03:00
# ifdef SA_STACK
{ SA_STACK , " SA_STACK " } ,
# endif
# ifdef SA_RESTART
{ SA_RESTART , " SA_RESTART " } ,
# endif
# ifdef SA_INTERRUPT
{ SA_INTERRUPT , " SA_INTERRUPT " } ,
# endif
2008-07-18 05:02:41 +04:00
# ifdef SA_NODEFER
{ SA_NODEFER , " SA_NODEFER " } ,
# endif
# if defined SA_NOMASK && SA_NODEFER != SA_NOMASK
1999-02-19 03:21:36 +03:00
{ SA_NOMASK , " SA_NOMASK " } ,
# endif
2008-07-18 05:02:41 +04:00
# ifdef SA_RESETHAND
{ SA_RESETHAND , " SA_RESETHAND " } ,
# endif
# if defined SA_ONESHOT && SA_ONESHOT != SA_RESETHAND
1999-02-19 03:21:36 +03:00
{ SA_ONESHOT , " SA_ONESHOT " } ,
# endif
# ifdef SA_SIGINFO
{ SA_SIGINFO , " SA_SIGINFO " } ,
# endif
# ifdef SA_RESETHAND
{ SA_RESETHAND , " SA_RESETHAND " } ,
# endif
# ifdef SA_ONSTACK
{ SA_ONSTACK , " SA_ONSTACK " } ,
# endif
# ifdef SA_NODEFER
{ SA_NODEFER , " SA_NODEFER " } ,
# endif
# ifdef SA_NOCLDSTOP
{ SA_NOCLDSTOP , " SA_NOCLDSTOP " } ,
# endif
# ifdef SA_NOCLDWAIT
{ SA_NOCLDWAIT , " SA_NOCLDWAIT " } ,
# endif
# ifdef _SA_BSDCALL
{ _SA_BSDCALL , " _SA_BSDCALL " } ,
2009-12-28 18:00:15 +03:00
# endif
# ifdef SA_NOPTRACE
{ SA_NOPTRACE , " SA_NOPTRACE " } ,
1999-02-19 03:21:36 +03:00
# endif
{ 0 , NULL } ,
} ;
2004-09-04 07:39:20 +04:00
static const struct xlat sigprocmaskcmds [ ] = {
1999-02-19 03:21:36 +03:00
{ SIG_BLOCK , " SIG_BLOCK " } ,
{ SIG_UNBLOCK , " SIG_UNBLOCK " } ,
{ SIG_SETMASK , " SIG_SETMASK " } ,
# ifdef SIG_SETMASK32
{ SIG_SETMASK32 , " SIG_SETMASK32 " } ,
# endif
{ 0 , NULL } ,
} ;
# endif /* HAVE_SIGACTION */
1999-03-30 03:23:13 +04:00
/* Anonymous realtime signals. */
/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
constant . This is what we want . Otherwise , just use SIGRTMIN . */
# ifdef SIGRTMIN
# ifndef __SIGRTMIN
# define __SIGRTMIN SIGRTMIN
# define __SIGRTMAX SIGRTMAX /* likewise */
# endif
# endif
Set saner MAX_ARGS (6 or 8) for X86_64 and I386
I noticed that tcp->u_args[MAX_ARGS] array is way larger than
I'd expect: for all arches except HPPA it has 32 (!) elements.
I looked at the code and so far I spotted only one abuser of
this fact: sys_sigreturn. On several arches, it saves sigset_t
into tcp->u_args[1...N] on entry and prints it on exit, a-la
memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t))
The problem here is that in glibc sigset_t is insanely large:
128 bytes, and using sizeof(sigset_t) in memcpy will overrun
&tcp->u_args[1] even with MAX_ARGS == 32:
On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes!
We may already have a bug there!
This commit changes the code to save NSIG / 8 bytes only.
NSIG can't ever be > 256, and in practice is <= 129,
thus NSIG / 8 is <= 16 bytes == 4 32-bit words,
and even MAX_ARGS == 5 should be enough for saving signal masks.
* defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8
for FreeBSD and to 6 for everyone else. Add comment about current
state of needed MAX_ARGS.
* signal.c: Add comment about size of sigset_t.
(sprintsigmask): Reduce static string buffer from 8k to 2k.
(sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes,
not sizeof(sigset_t) bytes.
* linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7.
* linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
/* Note on the size of sigset_t:
*
* In glibc , sigset_t is an array with space for 1024 bits ( ! ) ,
* even though all arches supported by Linux have only 64 signals
* except MIPS , which has 128. IOW , it is 128 bytes long .
*
* In - kernel sigset_t is sized correctly ( it is either 64 or 128 bit long ) .
* However , some old syscall return only 32 lower bits ( one word ) .
* Example : sys_sigpending vs sys_rt_sigpending .
*
* Be aware of this fact when you try to
* memcpy ( & tcp - > u_arg [ 1 ] , & something , sizeof ( sigset_t ) )
* - sizeof ( sigset_t ) is much bigger than you think ,
* it may overflow tcp - > u_arg [ ] array , and it may try to copy more data
* than is really available in < something > .
* Similarly ,
* umoven ( tcp , addr , sizeof ( sigset_t ) , & sigset )
* may be a bad idea : it ' ll try to read much more data than needed
* to fetch a sigset_t .
* Use ( NSIG / 8 ) as a size instead .
*/
2004-09-03 Roland McGrath <roland@redhat.com>
* syscall.c (sysent0, sysent1, sysent2, sysent): Add const to defn.
(nsyscalls0, nsyscalls1, nsyscalls2): Likewise.
(errnoent0, errnoent1, errnoent2, errnoent): Likewise.
(nerrnos0, nerrnos1, nerrnos2): Likewise.
* signal.c (signalent0, signalent1, signalent2): Likewise.
(nsignals0, nsignals1, nsignals2): Likewise.
(signame): LIkewise.
* ioctl.c (ioctlent0, ioctlent1, ioctlent2): Likewise.
(nioctlents0, nioctlents1, nioctlents2): Likewise.
(ioctl_lookup, ioctl_next_match): Likewise.
* defs.h: Update decls.
* io.c (sys_ioctl): Update users.
2004-09-04 07:53:10 +04:00
const char *
2011-06-09 03:28:11 +04:00
signame ( int sig )
1999-03-30 03:23:13 +04:00
{
2011-08-18 14:48:56 +04:00
static char buf [ sizeof ( " SIGRT_%d " ) + sizeof ( int ) * 3 ] ;
if ( sig > = 0 & & sig < nsignals )
1999-03-30 03:23:13 +04:00
return signalent [ sig ] ;
# ifdef SIGRTMIN
2011-08-18 14:48:56 +04:00
if ( sig > = __SIGRTMIN & & sig < = __SIGRTMAX ) {
sprintf ( buf , " SIGRT_%d " , ( int ) ( sig - __SIGRTMIN ) ) ;
1999-03-30 03:23:13 +04:00
return buf ;
}
2011-08-18 14:48:56 +04:00
# endif
sprintf ( buf , " %d " , sig ) ;
return buf ;
1999-03-30 03:23:13 +04:00
}
1999-02-19 03:21:36 +03:00
1999-04-06 05:19:39 +04:00
static void
2011-06-09 03:28:11 +04:00
long_to_sigset ( long l , sigset_t * s )
1999-04-06 05:19:39 +04:00
{
sigemptyset ( s ) ;
* ( long * ) s = l ;
}
static int
2011-05-30 16:00:14 +04:00
copy_sigset_len ( struct tcb * tcp , long addr , sigset_t * s , int len )
1999-04-06 05:19:39 +04:00
{
if ( len > sizeof ( * s ) )
len = sizeof ( * s ) ;
sigemptyset ( s ) ;
if ( umoven ( tcp , addr , len , ( char * ) s ) < 0 )
return - 1 ;
return 0 ;
}
/* Original sigset is unsigned long */
# define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(long))
2007-01-12 01:05:04 +03:00
static const char *
sprintsigmask ( const char * str , sigset_t * mask , int rt )
/* set might include realtime sigs */
1999-02-19 03:21:36 +03:00
{
Set saner MAX_ARGS (6 or 8) for X86_64 and I386
I noticed that tcp->u_args[MAX_ARGS] array is way larger than
I'd expect: for all arches except HPPA it has 32 (!) elements.
I looked at the code and so far I spotted only one abuser of
this fact: sys_sigreturn. On several arches, it saves sigset_t
into tcp->u_args[1...N] on entry and prints it on exit, a-la
memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t))
The problem here is that in glibc sigset_t is insanely large:
128 bytes, and using sizeof(sigset_t) in memcpy will overrun
&tcp->u_args[1] even with MAX_ARGS == 32:
On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes!
We may already have a bug there!
This commit changes the code to save NSIG / 8 bytes only.
NSIG can't ever be > 256, and in practice is <= 129,
thus NSIG / 8 is <= 16 bytes == 4 32-bit words,
and even MAX_ARGS == 5 should be enough for saving signal masks.
* defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8
for FreeBSD and to 6 for everyone else. Add comment about current
state of needed MAX_ARGS.
* signal.c: Add comment about size of sigset_t.
(sprintsigmask): Reduce static string buffer from 8k to 2k.
(sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes,
not sizeof(sigset_t) bytes.
* linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7.
* linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
/* Was [8 * sizeof(sigset_t) * 8], but
* glibc sigset_t is huge ( 1024 bits = 128 * bytes * ) ,
* and we were ending up with 8 k ( ! ) buffer here .
*
* No Unix system can have sig > 255
* ( waitpid API won ' t be able to indicate death from one )
* and sig 0 doesn ' t exist either .
* Therefore max possible no of sigs is 255 : 1. .255
*/
2012-01-30 01:38:35 +04:00
static char outstr [ 8 * ( 255 * 2 / 3 ) ] ;
Set saner MAX_ARGS (6 or 8) for X86_64 and I386
I noticed that tcp->u_args[MAX_ARGS] array is way larger than
I'd expect: for all arches except HPPA it has 32 (!) elements.
I looked at the code and so far I spotted only one abuser of
this fact: sys_sigreturn. On several arches, it saves sigset_t
into tcp->u_args[1...N] on entry and prints it on exit, a-la
memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t))
The problem here is that in glibc sigset_t is insanely large:
128 bytes, and using sizeof(sigset_t) in memcpy will overrun
&tcp->u_args[1] even with MAX_ARGS == 32:
On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes!
We may already have a bug there!
This commit changes the code to save NSIG / 8 bytes only.
NSIG can't ever be > 256, and in practice is <= 129,
thus NSIG / 8 is <= 16 bytes == 4 32-bit words,
and even MAX_ARGS == 5 should be enough for saving signal masks.
* defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8
for FreeBSD and to 6 for everyone else. Add comment about current
state of needed MAX_ARGS.
* signal.c: Add comment about size of sigset_t.
(sprintsigmask): Reduce static string buffer from 8k to 2k.
(sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes,
not sizeof(sigset_t) bytes.
* linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7.
* linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
1999-02-19 03:21:36 +03:00
int i , nsigs ;
1999-04-06 05:19:39 +04:00
int maxsigs ;
2012-01-30 01:38:35 +04:00
int show_members ;
char sep ;
2010-09-07 02:08:24 +04:00
char * s ;
1999-02-19 03:21:36 +03:00
1999-04-06 05:19:39 +04:00
maxsigs = nsignals ;
# ifdef __SIGRTMAX
if ( rt )
maxsigs = __SIGRTMAX ; /* instead */
# endif
2012-01-30 01:38:35 +04:00
s = stpcpy ( outstr , str ) ;
nsigs = 0 ;
1999-04-06 05:19:39 +04:00
for ( i = 1 ; i < maxsigs ; i + + ) {
1999-02-19 03:21:36 +03:00
if ( sigismember ( mask , i ) = = 1 )
nsigs + + ;
}
2012-01-30 01:38:35 +04:00
/* 1: show mask members, 0: show those which are NOT in mask */
show_members = ( nsigs < nsignals * 2 / 3 ) ;
if ( ! show_members )
1999-02-19 03:21:36 +03:00
* s + + = ' ~ ' ;
2012-01-30 01:38:35 +04:00
sep = ' [ ' ;
1999-04-06 05:19:39 +04:00
for ( i = 1 ; i < maxsigs ; i + + ) {
2012-01-30 01:38:35 +04:00
if ( sigismember ( mask , i ) = = show_members ) {
2001-03-06 18:08:09 +03:00
/* real-time signals on solaris don't have
* signalent entries
*/
2012-01-30 01:38:35 +04:00
char tsig [ 40 ] ;
* s + + = sep ;
2001-03-06 18:08:09 +03:00
if ( i < nsignals ) {
2012-01-30 01:38:35 +04:00
s = stpcpy ( s , signalent [ i ] + 3 ) ;
2001-03-06 18:08:09 +03:00
}
2003-09-24 02:19:32 +04:00
# ifdef SIGRTMIN
else if ( i > = __SIGRTMIN & & i < = __SIGRTMAX ) {
sprintf ( tsig , " RT_%u " , i - __SIGRTMIN ) ;
2012-01-30 01:38:35 +04:00
s = stpcpy ( s , tsig ) ;
2003-09-24 02:19:32 +04:00
}
# endif /* SIGRTMIN */
2001-03-06 18:08:09 +03:00
else {
sprintf ( tsig , " %u " , i ) ;
2012-01-30 01:38:35 +04:00
s = stpcpy ( s , tsig ) ;
2001-03-06 18:08:09 +03:00
}
2012-01-30 01:38:35 +04:00
sep = ' ' ;
1999-02-19 03:21:36 +03:00
}
}
2012-01-30 01:38:35 +04:00
if ( sep = = ' [ ' )
* s + + = sep ;
1999-02-19 03:21:36 +03:00
* s + + = ' ] ' ;
* s = ' \0 ' ;
return outstr ;
}
static void
2011-06-09 03:28:11 +04:00
printsigmask ( sigset_t * mask , int rt )
1999-02-19 03:21:36 +03:00
{
2011-09-01 11:55:05 +04:00
tprints ( sprintsigmask ( " " , mask , rt ) ) ;
1999-02-19 03:21:36 +03:00
}
void
2011-06-09 03:28:11 +04:00
printsignal ( int nr )
1999-02-19 03:21:36 +03:00
{
2011-09-01 11:55:05 +04:00
tprints ( signame ( nr ) ) ;
1999-02-19 03:21:36 +03:00
}
2006-10-13 Ulrich Drepper <drepper@redhat.com>
Bernhard Kaindl <bk@suse.de>
Dmitry V. Levin <ldv@altlinux.org>
Michael Holzheu <holzheu@de.ibm.com>
Add hooks for new syscalls. Add decoders for *at, inotify*,
pselect6, ppoll and unshare syscalls.
* defs.h: Declare print_sigset.
* desc.c (sys_pselect6): New function.
* file.c (decode_open, decode_access, decode_mkdir,
decode_readlink, decode_chmod, decode_utimes, decode_mknod):
New functions.
(sys_open, sys_access, sys_mkdir, sys_readlink, sys_chmod,
sys_utimes, sys_mknod): Use them.
[LINUX] (fstatatflags, unlinkatflags, inotify_modes): New
variables.
[LINUX] (print_dirfd, sys_openat, sys_faccessat,
sys_newfstatat, sys_mkdirat, sys_linkat, sys_unlinkat,
sys_symlinkat, sys_readlinkat, sys_renameat, sys_fchownat,
sys_fchmodat, sys_futimesat, sys_mknodat, sys_inotify_add_watch,
sys_inotify_rm_watch): New functions.
* process.c [LINUX] (sys_unshare): New function.
* signal.c (print_sigset): New function.
(sys_sigprocmask): Use it.
* stream.c (decode_poll): New function.
(sys_poll): Use it.
[LINUX] (sys_ppoll): New function.
* linux/syscall.h: Delcare new syscall handlers.
* linux/syscallent.h: Hook up new syscalls.
* linux/alpha/syscallent.h: Likewise.
* linux/hppa/syscallent.h: Likewise.
* linux/ia64/syscallent.h: Likewise.
* linux/mips/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/sparc64/syscallent.h: Likewise.
* linux/x86_64/syscallent.h: Likewise.
Fixes RH#178633.
2006-10-14 00:25:12 +04:00
void
print_sigset ( struct tcb * tcp , long addr , int rt )
{
sigset_t ss ;
if ( ! addr )
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
2006-10-13 Ulrich Drepper <drepper@redhat.com>
Bernhard Kaindl <bk@suse.de>
Dmitry V. Levin <ldv@altlinux.org>
Michael Holzheu <holzheu@de.ibm.com>
Add hooks for new syscalls. Add decoders for *at, inotify*,
pselect6, ppoll and unshare syscalls.
* defs.h: Declare print_sigset.
* desc.c (sys_pselect6): New function.
* file.c (decode_open, decode_access, decode_mkdir,
decode_readlink, decode_chmod, decode_utimes, decode_mknod):
New functions.
(sys_open, sys_access, sys_mkdir, sys_readlink, sys_chmod,
sys_utimes, sys_mknod): Use them.
[LINUX] (fstatatflags, unlinkatflags, inotify_modes): New
variables.
[LINUX] (print_dirfd, sys_openat, sys_faccessat,
sys_newfstatat, sys_mkdirat, sys_linkat, sys_unlinkat,
sys_symlinkat, sys_readlinkat, sys_renameat, sys_fchownat,
sys_fchmodat, sys_futimesat, sys_mknodat, sys_inotify_add_watch,
sys_inotify_rm_watch): New functions.
* process.c [LINUX] (sys_unshare): New function.
* signal.c (print_sigset): New function.
(sys_sigprocmask): Use it.
* stream.c (decode_poll): New function.
(sys_poll): Use it.
[LINUX] (sys_ppoll): New function.
* linux/syscall.h: Delcare new syscall handlers.
* linux/syscallent.h: Hook up new syscalls.
* linux/alpha/syscallent.h: Likewise.
* linux/hppa/syscallent.h: Likewise.
* linux/ia64/syscallent.h: Likewise.
* linux/mips/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/sparc64/syscallent.h: Likewise.
* linux/x86_64/syscallent.h: Likewise.
Fixes RH#178633.
2006-10-14 00:25:12 +04:00
else if ( copy_sigset ( tcp , addr , & ss ) < 0 )
tprintf ( " %#lx " , addr ) ;
else
printsigmask ( & ss , rt ) ;
}
2001-10-18 19:13:53 +04:00
# ifndef ILL_ILLOPC
# define ILL_ILLOPC 1 /* illegal opcode */
# define ILL_ILLOPN 2 /* illegal operand */
# define ILL_ILLADR 3 /* illegal addressing mode */
# define ILL_ILLTRP 4 /* illegal trap */
# define ILL_PRVOPC 5 /* privileged opcode */
# define ILL_PRVREG 6 /* privileged register */
# define ILL_COPROC 7 /* coprocessor error */
# define ILL_BADSTK 8 /* internal stack error */
# define FPE_INTDIV 1 /* integer divide by zero */
# define FPE_INTOVF 2 /* integer overflow */
# define FPE_FLTDIV 3 /* floating point divide by zero */
# define FPE_FLTOVF 4 /* floating point overflow */
# define FPE_FLTUND 5 /* floating point underflow */
# define FPE_FLTRES 6 /* floating point inexact result */
# define FPE_FLTINV 7 /* floating point invalid operation */
# define FPE_FLTSUB 8 /* subscript out of range */
# define SEGV_MAPERR 1 /* address not mapped to object */
# define SEGV_ACCERR 2 /* invalid permissions for mapped object */
# define BUS_ADRALN 1 /* invalid address alignment */
# define BUS_ADRERR 2 /* non-existant physical address */
# define BUS_OBJERR 3 /* object specific hardware error */
# define TRAP_BRKPT 1 /* process breakpoint */
# define TRAP_TRACE 2 /* process trace trap */
# define CLD_EXITED 1 /* child has exited */
# define CLD_KILLED 2 /* child was killed */
# define CLD_DUMPED 3 /* child terminated abnormally */
# define CLD_TRAPPED 4 /* traced child has trapped */
# define CLD_STOPPED 5 /* child has stopped */
# define CLD_CONTINUED 6 /* stopped child has continued */
# define POLL_IN 1 /* data input available */
# define POLL_OUT 2 /* output buffers available */
# define POLL_MSG 3 /* input message available */
# define POLL_ERR 4 /* i/o error */
# define POLL_PRI 5 /* high priority input available */
# define POLL_HUP 6 /* device disconnected */
2011-03-11 00:41:34 +03:00
# define SI_KERNEL 0x80 /* sent by kernel */
2001-10-18 19:13:53 +04:00
# define SI_USER 0 /* sent by kill, sigsend, raise */
# define SI_QUEUE -1 /* sent by sigqueue */
# define SI_TIMER -2 /* sent by timer expiration */
# define SI_MESGQ -3 /* sent by real time mesq state change */
# define SI_ASYNCIO -4 /* sent by AIO completion */
2011-03-11 00:41:34 +03:00
# define SI_SIGIO -5 /* sent by SIGIO */
# define SI_TKILL -6 /* sent by tkill */
# define SI_ASYNCNL -60 /* sent by asynch name lookup completion */
2011-03-11 01:18:56 +03:00
# define SI_FROMUSER(sip) ((sip)->si_code <= 0)
2012-02-25 05:38:52 +04:00
# endif
2001-10-18 19:13:53 +04:00
# if __GLIBC_MINOR__ < 1
/* Type for data associated with a signal. */
typedef union sigval
{
int sival_int ;
void * sival_ptr ;
} sigval_t ;
# define __SI_MAX_SIZE 128
2011-06-07 14:13:24 +04:00
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof(int)) - 3)
2001-10-18 19:13:53 +04:00
typedef struct siginfo
{
int si_signo ; /* Signal number. */
int si_errno ; /* If non-zero, an errno value associated with
this signal , as defined in < errno . h > . */
int si_code ; /* Signal code. */
union
{
int _pad [ __SI_PAD_SIZE ] ;
/* kill(). */
struct
{
__pid_t si_pid ; /* Sending process ID. */
__uid_t si_uid ; /* Real user ID of sending process. */
} _kill ;
/* POSIX.1b timers. */
struct
{
unsigned int _timer1 ;
unsigned int _timer2 ;
} _timer ;
/* POSIX.1b signals. */
struct
{
__pid_t si_pid ; /* Sending process ID. */
__uid_t si_uid ; /* Real user ID of sending process. */
sigval_t si_sigval ; /* Signal value. */
} _rt ;
/* SIGCHLD. */
struct
{
__pid_t si_pid ; /* Which child. */
int si_status ; /* Exit value or signal. */
__clock_t si_utime ;
__clock_t si_stime ;
} _sigchld ;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
struct
{
void * si_addr ; /* Faulting insn/memory ref. */
} _sigfault ;
/* SIGPOLL. */
struct
{
int si_band ; /* Band event for SIGPOLL. */
int si_fd ;
} _sigpoll ;
} _sifields ;
} siginfo_t ;
# define si_pid _sifields._kill.si_pid
# define si_uid _sifields._kill.si_uid
# define si_status _sifields._sigchld.si_status
# define si_utime _sifields._sigchld.si_utime
# define si_stime _sifields._sigchld.si_stime
# define si_value _sifields._rt.si_sigval
# define si_int _sifields._rt.si_sigval.sival_int
# define si_ptr _sifields._rt.si_sigval.sival_ptr
# define si_addr _sifields._sigfault.si_addr
# define si_band _sifields._sigpoll.si_band
# define si_fd _sifields._sigpoll.si_fd
# endif
2004-09-04 07:39:20 +04:00
static const struct xlat siginfo_codes [ ] = {
2011-03-11 00:41:34 +03:00
# ifdef SI_KERNEL
{ SI_KERNEL , " SI_KERNEL " } ,
2001-10-18 19:13:53 +04:00
# endif
# ifdef SI_USER
{ SI_USER , " SI_USER " } ,
# endif
# ifdef SI_QUEUE
{ SI_QUEUE , " SI_QUEUE " } ,
# endif
# ifdef SI_TIMER
{ SI_TIMER , " SI_TIMER " } ,
# endif
# ifdef SI_MESGQ
{ SI_MESGQ , " SI_MESGQ " } ,
2003-05-23 04:29:02 +04:00
# endif
2011-03-11 00:41:34 +03:00
# ifdef SI_ASYNCIO
{ SI_ASYNCIO , " SI_ASYNCIO " } ,
# endif
2003-05-23 04:29:02 +04:00
# ifdef SI_SIGIO
{ SI_SIGIO , " SI_SIGIO " } ,
# endif
# ifdef SI_TKILL
{ SI_TKILL , " SI_TKILL " } ,
2011-03-11 00:41:34 +03:00
# endif
# ifdef SI_ASYNCNL
{ SI_ASYNCNL , " SI_ASYNCNL " } ,
# endif
# ifdef SI_NOINFO
{ SI_NOINFO , " SI_NOINFO " } ,
# endif
# ifdef SI_LWP
{ SI_LWP , " SI_LWP " } ,
2001-10-18 19:13:53 +04:00
# endif
{ 0 , NULL } ,
} ;
2004-09-04 07:39:20 +04:00
static const struct xlat sigill_codes [ ] = {
2001-10-18 19:13:53 +04:00
{ ILL_ILLOPC , " ILL_ILLOPC " } ,
{ ILL_ILLOPN , " ILL_ILLOPN " } ,
{ ILL_ILLADR , " ILL_ILLADR " } ,
{ ILL_ILLTRP , " ILL_ILLTRP " } ,
{ ILL_PRVOPC , " ILL_PRVOPC " } ,
{ ILL_PRVREG , " ILL_PRVREG " } ,
{ ILL_COPROC , " ILL_COPROC " } ,
{ ILL_BADSTK , " ILL_BADSTK " } ,
{ 0 , NULL } ,
} ;
2004-09-04 07:39:20 +04:00
static const struct xlat sigfpe_codes [ ] = {
2001-10-18 19:13:53 +04:00
{ FPE_INTDIV , " FPE_INTDIV " } ,
{ FPE_INTOVF , " FPE_INTOVF " } ,
{ FPE_FLTDIV , " FPE_FLTDIV " } ,
{ FPE_FLTOVF , " FPE_FLTOVF " } ,
{ FPE_FLTUND , " FPE_FLTUND " } ,
{ FPE_FLTRES , " FPE_FLTRES " } ,
{ FPE_FLTINV , " FPE_FLTINV " } ,
{ FPE_FLTSUB , " FPE_FLTSUB " } ,
{ 0 , NULL } ,
} ;
2004-09-04 07:39:20 +04:00
static const struct xlat sigtrap_codes [ ] = {
2001-10-18 19:13:53 +04:00
{ TRAP_BRKPT , " TRAP_BRKPT " } ,
{ TRAP_TRACE , " TRAP_TRACE " } ,
{ 0 , NULL } ,
} ;
2004-09-04 07:39:20 +04:00
static const struct xlat sigchld_codes [ ] = {
2001-10-18 19:13:53 +04:00
{ CLD_EXITED , " CLD_EXITED " } ,
{ CLD_KILLED , " CLD_KILLED " } ,
{ CLD_DUMPED , " CLD_DUMPED " } ,
{ CLD_TRAPPED , " CLD_TRAPPED " } ,
{ CLD_STOPPED , " CLD_STOPPED " } ,
{ CLD_CONTINUED , " CLD_CONTINUED " } ,
{ 0 , NULL } ,
} ;
2004-09-04 07:39:20 +04:00
static const struct xlat sigpoll_codes [ ] = {
2001-10-18 19:13:53 +04:00
{ POLL_IN , " POLL_IN " } ,
{ POLL_OUT , " POLL_OUT " } ,
{ POLL_MSG , " POLL_MSG " } ,
{ POLL_ERR , " POLL_ERR " } ,
{ POLL_PRI , " POLL_PRI " } ,
{ POLL_HUP , " POLL_HUP " } ,
{ 0 , NULL } ,
} ;
2004-09-04 07:39:20 +04:00
static const struct xlat sigprof_codes [ ] = {
2001-10-18 19:13:53 +04:00
# ifdef PROF_SIG
{ PROF_SIG , " PROF_SIG " } ,
# endif
{ 0 , NULL } ,
} ;
# ifdef SIGEMT
2004-09-04 07:39:20 +04:00
static const struct xlat sigemt_codes [ ] = {
2001-10-18 19:13:53 +04:00
# ifdef EMT_TAGOVF
{ EMT_TAGOVF , " EMT_TAGOVF " } ,
# endif
{ 0 , NULL } ,
} ;
# endif
2004-09-04 07:39:20 +04:00
static const struct xlat sigsegv_codes [ ] = {
2001-10-18 19:13:53 +04:00
{ SEGV_MAPERR , " SEGV_MAPERR " } ,
{ SEGV_ACCERR , " SEGV_ACCERR " } ,
{ 0 , NULL } ,
} ;
2004-09-04 07:39:20 +04:00
static const struct xlat sigbus_codes [ ] = {
2001-10-18 19:13:53 +04:00
{ BUS_ADRALN , " BUS_ADRALN " } ,
{ BUS_ADRERR , " BUS_ADRERR " } ,
{ BUS_OBJERR , " BUS_OBJERR " } ,
{ 0 , NULL } ,
} ;
void
2011-03-11 01:18:56 +03:00
printsiginfo ( siginfo_t * sip , int verbose )
2001-10-18 19:13:53 +04:00
{
2004-10-07 02:11:54 +04:00
const char * code ;
2001-10-18 19:13:53 +04:00
if ( sip - > si_signo = = 0 ) {
2011-09-01 12:00:28 +04:00
tprints ( " {} " ) ;
2001-10-18 19:13:53 +04:00
return ;
}
2011-09-01 12:00:28 +04:00
tprints ( " {si_signo= " ) ;
2001-10-18 19:13:53 +04:00
printsignal ( sip - > si_signo ) ;
code = xlookup ( siginfo_codes , sip - > si_code ) ;
if ( ! code ) {
switch ( sip - > si_signo ) {
case SIGTRAP :
code = xlookup ( sigtrap_codes , sip - > si_code ) ;
break ;
case SIGCHLD :
code = xlookup ( sigchld_codes , sip - > si_code ) ;
break ;
case SIGPOLL :
code = xlookup ( sigpoll_codes , sip - > si_code ) ;
break ;
case SIGPROF :
code = xlookup ( sigprof_codes , sip - > si_code ) ;
break ;
case SIGILL :
code = xlookup ( sigill_codes , sip - > si_code ) ;
break ;
# ifdef SIGEMT
case SIGEMT :
code = xlookup ( sigemt_codes , sip - > si_code ) ;
break ;
# endif
case SIGFPE :
code = xlookup ( sigfpe_codes , sip - > si_code ) ;
break ;
case SIGSEGV :
code = xlookup ( sigsegv_codes , sip - > si_code ) ;
break ;
case SIGBUS :
code = xlookup ( sigbus_codes , sip - > si_code ) ;
break ;
}
}
if ( code )
tprintf ( " , si_code=%s " , code ) ;
else
tprintf ( " , si_code=%#x " , sip - > si_code ) ;
# ifdef SI_NOINFO
if ( sip - > si_code ! = SI_NOINFO )
# endif
{
if ( sip - > si_errno ) {
if ( sip - > si_errno < 0 | | sip - > si_errno > = nerrnos )
tprintf ( " , si_errno=%d " , sip - > si_errno ) ;
else
tprintf ( " , si_errno=%s " ,
errnoent [ sip - > si_errno ] ) ;
}
# ifdef SI_FROMUSER
if ( SI_FROMUSER ( sip ) ) {
2011-03-11 01:18:56 +03:00
tprintf ( " , si_pid=%lu, si_uid=%lu " ,
( unsigned long ) sip - > si_pid ,
( unsigned long ) sip - > si_uid ) ;
2001-10-18 19:13:53 +04:00
switch ( sip - > si_code ) {
2011-03-11 01:18:56 +03:00
# ifdef SI_USER
case SI_USER :
break ;
# endif
# ifdef SI_TKILL
case SI_TKILL :
break ;
# endif
2001-10-18 19:13:53 +04:00
# ifdef SI_TIMER
case SI_TIMER :
2011-03-11 01:18:56 +03:00
tprintf ( " , si_value=%d " , sip - > si_int ) ;
2001-10-18 19:13:53 +04:00
break ;
2011-03-11 01:18:56 +03:00
# endif
default :
2011-03-11 02:14:47 +03:00
if ( ! sip - > si_ptr )
break ;
2011-03-11 01:18:56 +03:00
if ( ! verbose )
2011-09-01 12:00:28 +04:00
tprints ( " , ... " ) ;
2011-03-11 01:18:56 +03:00
else
tprintf ( " , si_value={int=%u, ptr=%#lx} " ,
sip - > si_int ,
( unsigned long ) sip - > si_ptr ) ;
break ;
2001-10-18 19:13:53 +04:00
}
}
else
# endif /* SI_FROMUSER */
{
switch ( sip - > si_signo ) {
case SIGCHLD :
tprintf ( " , si_pid=%ld, si_status= " ,
( long ) sip - > si_pid ) ;
if ( sip - > si_code = = CLD_EXITED )
tprintf ( " %d " , sip - > si_status ) ;
else
printsignal ( sip - > si_status ) ;
if ( ! verbose )
2011-09-01 12:00:28 +04:00
tprints ( " , ... " ) ;
2001-10-18 19:13:53 +04:00
else
tprintf ( " , si_utime=%lu, si_stime=%lu " ,
sip - > si_utime ,
sip - > si_stime ) ;
break ;
case SIGILL : case SIGFPE :
case SIGSEGV : case SIGBUS :
tprintf ( " , si_addr=%#lx " ,
( unsigned long ) sip - > si_addr ) ;
break ;
case SIGPOLL :
switch ( sip - > si_code ) {
case POLL_IN : case POLL_OUT : case POLL_MSG :
tprintf ( " , si_band=%ld " ,
( long ) sip - > si_band ) ;
break ;
}
break ;
default :
2011-03-11 02:14:47 +03:00
if ( sip - > si_pid | | sip - > si_uid )
tprintf ( " , si_pid=%lu, si_uid=%lu " ,
( unsigned long ) sip - > si_pid ,
( unsigned long ) sip - > si_uid ) ;
if ( ! sip - > si_ptr )
break ;
2001-10-18 19:13:53 +04:00
if ( ! verbose )
2011-09-01 12:00:28 +04:00
tprints ( " , ... " ) ;
2001-10-18 19:13:53 +04:00
else {
2011-03-11 02:14:47 +03:00
tprintf ( " , si_value={int=%u, ptr=%#lx} " ,
2001-10-18 19:13:53 +04:00
sip - > si_int ,
( unsigned long ) sip - > si_ptr ) ;
}
2002-12-17 08:10:37 +03:00
2001-10-18 19:13:53 +04:00
}
}
}
2011-09-01 12:00:28 +04:00
tprints ( " } " ) ;
2001-10-18 19:13:53 +04:00
}
1999-02-19 03:21:36 +03:00
int
2011-05-30 16:00:14 +04:00
sys_sigsetmask ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( entering ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 0 ] , & sigm ) ;
printsigmask ( & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
}
else if ( ! syserror ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_rval , & sigm ) ;
tcp - > auxstr = sprintsigmask ( " old mask " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_HEX | RVAL_STR ;
}
return 0 ;
}
# ifdef HAVE_SIGACTION
struct old_sigaction {
__sighandler_t __sa_handler ;
unsigned long sa_mask ;
unsigned long sa_flags ;
void ( * sa_restorer ) ( void ) ;
} ;
1999-05-09 04:29:58 +04:00
# define SA_HANDLER __sa_handler
2002-12-17 08:10:37 +03:00
# ifndef SA_HANDLER
# define SA_HANDLER sa_handler
1999-02-19 03:21:36 +03:00
# endif
int
2011-05-30 16:00:14 +04:00
sys_sigaction ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
long addr ;
2001-03-06 12:25:46 +03:00
sigset_t sigset ;
1999-02-19 03:21:36 +03:00
struct old_sigaction sa ;
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
addr = tcp - > u_arg [ 1 ] ;
} else
addr = tcp - > u_arg [ 2 ] ;
if ( addr = = 0 )
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
1999-02-19 03:21:36 +03:00
else if ( ! verbose ( tcp ) )
tprintf ( " %#lx " , addr ) ;
else if ( umove ( tcp , addr , & sa ) < 0 )
2011-09-01 12:00:28 +04:00
tprints ( " {...} " ) ;
1999-02-19 03:21:36 +03:00
else {
2009-09-09 22:13:19 +04:00
/* Architectures using function pointers, like
* hppa , may need to manipulate the function pointer
* to compute the result of a comparison . However ,
* the SA_HANDLER function pointer exists only in
* the address space of the traced process , and can ' t
* be manipulated by strace . In order to prevent the
* compiler from generating code to manipulate
* SA_HANDLER we cast the function pointers to long . */
if ( ( long ) sa . SA_HANDLER = = ( long ) SIG_ERR )
2011-09-01 12:00:28 +04:00
tprints ( " {SIG_ERR, " ) ;
2009-09-09 22:13:19 +04:00
else if ( ( long ) sa . SA_HANDLER = = ( long ) SIG_DFL )
2011-09-01 12:00:28 +04:00
tprints ( " {SIG_DFL, " ) ;
Get rid of TCB_SIGTRAPPED
On attempts to block or set SIGTRAP handler,
for example, using sigaction syscall, we generate
an additional SIGSTOP.
This change gets rid of this SIGSTOP sending/ignoring.
It appears to work just fine.
It also works if I force strace to not use PTRACE_O_TRACESYSGOOD,
which means strace stops will be marked with SIGTRAP,
not (SIGTRAP | 0x80) - I wondered maybe that's when
this hack is needed.
So, why we even have TCB_SIGTRAPPED? No one knows. It predates
version control: this code was present in the initial commit,
in 1999. No adequate comments, either.
Moreover, TCB_SIGTRAPPED is not set in sys_rt_sigaction
and sys_sigprocmask syscalls - the ones which are most usually
used to implement signal blocking, it is only set in obsolete
sys_signal, sys_sigaction, sys_sigsetmask, and in some dead
non-Linux code.
I think whatever bug it was fixing is gone long ago -
at least as long as sys_rt_sigaction is used by glibc.
Again, since glibc (and uclibc) uses sys_rt_sigaction
and sys_sigprocmask, modified code paths are not used
by most programs anyway.
* defs.h: Remove definition of TCB_SIGTRAPPED.
* signal.c (sys_sigvec): Don't set TCB_SIGTRAPPED and don't send SIGSTOP.
(sys_sigsetmask): Likewise.
(sys_sigaction): Likewise.
(sys_signal): Likewise.
* strace.c (trace): Remove code which executes if TCB_SIGTRAPPED is set.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-18 19:30:47 +04:00
else if ( ( long ) sa . SA_HANDLER = = ( long ) SIG_IGN )
2011-09-01 12:00:28 +04:00
tprints ( " {SIG_IGN, " ) ;
Get rid of TCB_SIGTRAPPED
On attempts to block or set SIGTRAP handler,
for example, using sigaction syscall, we generate
an additional SIGSTOP.
This change gets rid of this SIGSTOP sending/ignoring.
It appears to work just fine.
It also works if I force strace to not use PTRACE_O_TRACESYSGOOD,
which means strace stops will be marked with SIGTRAP,
not (SIGTRAP | 0x80) - I wondered maybe that's when
this hack is needed.
So, why we even have TCB_SIGTRAPPED? No one knows. It predates
version control: this code was present in the initial commit,
in 1999. No adequate comments, either.
Moreover, TCB_SIGTRAPPED is not set in sys_rt_sigaction
and sys_sigprocmask syscalls - the ones which are most usually
used to implement signal blocking, it is only set in obsolete
sys_signal, sys_sigaction, sys_sigsetmask, and in some dead
non-Linux code.
I think whatever bug it was fixing is gone long ago -
at least as long as sys_rt_sigaction is used by glibc.
Again, since glibc (and uclibc) uses sys_rt_sigaction
and sys_sigprocmask, modified code paths are not used
by most programs anyway.
* defs.h: Remove definition of TCB_SIGTRAPPED.
* signal.c (sys_sigvec): Don't set TCB_SIGTRAPPED and don't send SIGSTOP.
(sys_sigsetmask): Likewise.
(sys_sigaction): Likewise.
(sys_signal): Likewise.
* strace.c (trace): Remove code which executes if TCB_SIGTRAPPED is set.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-18 19:30:47 +04:00
else
1999-05-09 04:29:58 +04:00
tprintf ( " {%#lx, " , ( long ) sa . SA_HANDLER ) ;
2012-01-18 18:30:56 +04:00
long_to_sigset ( sa . sa_mask , & sigset ) ;
printsigmask ( & sigset , 0 ) ;
tprints ( " , " ) ;
printflags ( sigact_flags , sa . sa_flags , " SA_??? " ) ;
2002-12-16 02:58:41 +03:00
# ifdef SA_RESTORER
2012-01-18 18:30:56 +04:00
if ( sa . sa_flags & SA_RESTORER )
tprintf ( " , %p " , sa . sa_restorer ) ;
2002-12-16 02:58:41 +03:00
# endif
2012-01-18 18:30:56 +04:00
tprints ( " } " ) ;
1999-02-19 03:21:36 +03:00
}
if ( entering ( tcp ) )
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
else
tprintf ( " , %#lx " , ( unsigned long ) sa . sa_restorer ) ;
return 0 ;
}
int
2011-05-30 16:00:14 +04:00
sys_signal ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
switch ( tcp - > u_arg [ 1 ] ) {
2008-08-07 01:38:52 +04:00
case ( long ) SIG_ERR :
2011-09-01 12:00:28 +04:00
tprints ( " SIG_ERR " ) ;
1999-02-19 03:21:36 +03:00
break ;
2008-08-07 01:38:52 +04:00
case ( long ) SIG_DFL :
2011-09-01 12:00:28 +04:00
tprints ( " SIG_DFL " ) ;
1999-02-19 03:21:36 +03:00
break ;
2008-08-07 01:38:52 +04:00
case ( long ) SIG_IGN :
2011-09-01 12:00:28 +04:00
tprints ( " SIG_IGN " ) ;
1999-02-19 03:21:36 +03:00
break ;
default :
tprintf ( " %#lx " , tcp - > u_arg [ 1 ] ) ;
}
2000-08-10 06:14:04 +04:00
return 0 ;
}
2008-09-03 05:22:18 +04:00
else if ( ! syserror ( tcp ) ) {
2000-08-10 06:14:04 +04:00
switch ( tcp - > u_rval ) {
2008-08-07 01:38:52 +04:00
case ( long ) SIG_ERR :
2000-08-10 06:14:04 +04:00
tcp - > auxstr = " SIG_ERR " ; break ;
2008-08-07 01:38:52 +04:00
case ( long ) SIG_DFL :
2000-08-10 06:14:04 +04:00
tcp - > auxstr = " SIG_DFL " ; break ;
2008-08-07 01:38:52 +04:00
case ( long ) SIG_IGN :
2000-08-10 06:14:04 +04:00
tcp - > auxstr = " SIG_IGN " ; break ;
default :
tcp - > auxstr = NULL ;
}
return RVAL_HEX | RVAL_STR ;
}
2008-09-03 05:22:18 +04:00
return 0 ;
2000-08-10 06:14:04 +04:00
}
1999-02-19 03:21:36 +03:00
# endif /* HAVE_SIGACTION */
int
2009-02-25 20:08:40 +03:00
sys_sigreturn ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
2009-02-25 20:08:40 +03:00
# if defined(ARM)
2003-06-04 03:29:04 +04:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
struct pt_regs regs ;
struct sigcontext_struct sc ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2003-06-04 03:29:04 +04:00
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , NULL , ( void * ) & regs ) = = - 1 )
return 0 ;
if ( umove ( tcp , regs . ARM_sp , & sc ) < 0 )
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( sc . oldmask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
2003-06-04 03:29:04 +04:00
}
return 0 ;
# elif defined(S390) || defined(S390X)
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
long usp ;
struct sigcontext_struct sc ;
2011-06-07 14:13:24 +04:00
if ( upeek ( tcp , PT_GPR15 , & usp ) < 0 )
2003-06-04 03:29:04 +04:00
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
if ( umove ( tcp , usp + __SIGNAL_FRAMESIZE , & sc ) < 0 )
2003-06-04 03:29:04 +04:00
return 0 ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , ( sigset_t * ) & sc . oldmask [ 0 ] , 0 ) ) ;
2003-06-04 03:29:04 +04:00
}
return 0 ;
2009-02-25 20:08:40 +03:00
# elif defined(I386)
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
struct sigcontext_struct sc ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
/* Note: on i386, sc is followed on stack by struct fpstate
* and after it an additional u32 extramask [ 1 ] which holds
* upper half of the mask . We can fetch it there
* if / when we ' d want to display the full mask . . .
*/
1999-02-19 03:21:36 +03:00
sigset_t sigm ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
if ( umove ( tcp , i386_regs . esp , & sc ) < 0 )
1999-02-19 03:21:36 +03:00
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( sc . oldmask , & sigm ) ;
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
2009-02-25 20:08:40 +03:00
# elif defined(IA64)
2000-02-04 00:58:30 +03:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
struct sigcontext sc ;
long sp ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2000-05-01 05:53:59 +04:00
/* offset of sigcontext in the kernel's sigframe structure: */
# define SIGFRAME_SC_OFFSET 0x90
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , PT_R12 , & sp ) < 0 )
2000-02-04 00:58:30 +03:00
return 0 ;
2000-05-01 05:53:59 +04:00
if ( umove ( tcp , sp + 16 + SIGFRAME_SC_OFFSET , & sc ) < 0 )
2000-02-04 00:58:30 +03:00
return 0 ;
Set saner MAX_ARGS (6 or 8) for X86_64 and I386
I noticed that tcp->u_args[MAX_ARGS] array is way larger than
I'd expect: for all arches except HPPA it has 32 (!) elements.
I looked at the code and so far I spotted only one abuser of
this fact: sys_sigreturn. On several arches, it saves sigset_t
into tcp->u_args[1...N] on entry and prints it on exit, a-la
memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t))
The problem here is that in glibc sigset_t is insanely large:
128 bytes, and using sizeof(sigset_t) in memcpy will overrun
&tcp->u_args[1] even with MAX_ARGS == 32:
On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes!
We may already have a bug there!
This commit changes the code to save NSIG / 8 bytes only.
NSIG can't ever be > 256, and in practice is <= 129,
thus NSIG / 8 is <= 16 bytes == 4 32-bit words,
and even MAX_ARGS == 5 should be enough for saving signal masks.
* defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8
for FreeBSD and to 6 for everyone else. Add comment about current
state of needed MAX_ARGS.
* signal.c: Add comment about size of sigset_t.
(sprintsigmask): Reduce static string buffer from 8k to 2k.
(sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes,
not sizeof(sigset_t) bytes.
* linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7.
* linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
sigemptyset ( & sigm ) ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
memcpy ( & sigm , & sc . sc_mask , NSIG / 8 ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
2000-02-04 00:58:30 +03:00
}
return 0 ;
2009-02-25 20:08:40 +03:00
# elif defined(POWERPC)
2003-06-04 03:29:04 +04:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
long esp ;
struct sigcontext_struct sc ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
if ( upeek ( tcp , sizeof ( unsigned long ) * PT_R1 , & esp ) < 0 )
2003-06-04 03:29:04 +04:00
return 0 ;
2010-02-23 02:18:51 +03:00
/* Skip dummy stack frame. */
2010-07-12 23:39:57 +04:00
# ifdef POWERPC64
if ( current_personality = = 0 )
esp + = 128 ;
else
esp + = 64 ;
2010-02-23 02:18:51 +03:00
# else
esp + = 64 ;
# endif
2003-06-04 03:29:04 +04:00
if ( umove ( tcp , esp , & sc ) < 0 )
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( sc . oldmask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
2003-06-04 03:29:04 +04:00
}
return 0 ;
2009-02-25 20:08:40 +03:00
# elif defined(M68K)
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
long usp ;
struct sigcontext sc ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , 4 * PT_USP , & usp ) < 0 )
1999-02-19 03:21:36 +03:00
return 0 ;
2003-06-04 03:29:04 +04:00
if ( umove ( tcp , usp , & sc ) < 0 )
1999-02-19 03:21:36 +03:00
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( sc . sc_mask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
2009-02-25 20:08:40 +03:00
# elif defined(ALPHA)
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
long fp ;
struct sigcontext_struct sc ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_FP , & fp ) < 0 )
1999-02-19 03:21:36 +03:00
return 0 ;
2003-06-04 03:29:04 +04:00
if ( umove ( tcp , fp , & sc ) < 0 )
1999-02-19 03:21:36 +03:00
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( sc . sc_mask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
2012-02-25 05:47:15 +04:00
# elif defined(SPARC) || defined(SPARC64)
2011-06-07 14:13:24 +04:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
long i1 ;
struct pt_regs regs ;
m_siginfo_t si ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2011-06-09 03:36:29 +04:00
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " sigreturn: PTRACE_GETREGS " ) ;
return 0 ;
}
sparc/linux: Rewrite to use asm/ptrace.h
The current sparc/linux code uses asm/reg.h, but recent Linux kernels
dropped that header completely. So switch over to the ptrace headers
as those should stick around indefinitely as part of the ABI.
* defs.h [LINUXSPARC] (U_REG_G1, U_REG_O0, U_REG_O1): Define.
* process.c: Drop asm/regs.h include.
[SPARC || SPARC64] (change_syscall): Change struct regs to struct pt_regs.
* signal.c: Drop asm/regs.h include.
(m_siginfo_t): Unify [SPARC || SPARC64] and [MIPS].
[SPARC || SPARC64] (sys_sigreturn): Change struct regs to struct pt_regs.
* syscall.c: Drop asm/regs.h include.
[SPARC || SPARC64] (internal_syscall, get_scno, get_error, force_result,
syscall_enter): Change struct regs to struct pt_regs.
* util.c: Drop asm/regs.h include.
(_hack_syscall5, _ptrace): Delete.
[SPARC || SPARC64] (getpc, printcall, arg_setup_state): Change
struct regs to struct pt_regs.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2009-10-12 19:05:14 +04:00
i1 = regs . u_regs [ U_REG_O1 ] ;
2011-06-07 14:13:24 +04:00
if ( umove ( tcp , i1 , & si ) < 0 ) {
2011-06-09 03:36:29 +04:00
perror ( " sigreturn: umove " ) ;
1999-02-19 03:21:36 +03:00
return 0 ;
}
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( si . si_mask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
2012-02-25 05:47:15 +04:00
# elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64)
2008-05-20 05:11:56 +04:00
/* This decodes rt_sigreturn. The 64-bit ABIs do not have
sigreturn . */
2011-06-07 14:13:24 +04:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
long sp ;
struct ucontext uc ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2008-12-16 21:18:40 +03:00
if ( upeek ( tcp , REG_SP , & sp ) < 0 )
2009-02-27 23:32:52 +03:00
return 0 ;
2008-05-20 05:11:56 +04:00
/* There are six words followed by a 128-byte siginfo. */
sp = sp + 6 * 4 + 128 ;
if ( umove ( tcp , sp , & uc ) < 0 )
2009-02-27 23:32:52 +03:00
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( * ( long * ) & uc . uc_sigmask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
2008-05-20 05:11:56 +04:00
}
return 0 ;
2009-02-25 20:08:40 +03:00
# elif defined(MIPS)
2011-06-07 14:13:24 +04:00
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
long sp ;
struct pt_regs regs ;
m_siginfo_t si ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2011-06-09 03:36:29 +04:00
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " sigreturn: PTRACE_GETREGS " ) ;
return 0 ;
}
2007-11-04 03:00:00 +03:00
sp = regs . regs [ 29 ] ;
if ( umove ( tcp , sp , & si ) < 0 )
2011-06-09 03:22:10 +04:00
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( si . si_mask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
1999-11-01 00:15:38 +03:00
}
return 0 ;
2009-02-25 20:08:40 +03:00
# elif defined(CRISV10) || defined(CRISV32)
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
struct sigcontext sc ;
2009-02-25 20:08:40 +03:00
long regs [ PT_MAX + 1 ] ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2009-02-25 20:08:40 +03:00
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , NULL , ( long ) regs ) < 0 ) {
perror ( " sigreturn: PTRACE_GETREGS " ) ;
return 0 ;
}
if ( umove ( tcp , regs [ PT_USP ] , & sc ) < 0 )
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( sc . oldmask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
2009-02-25 20:08:40 +03:00
}
return 0 ;
2009-12-28 18:00:15 +03:00
# elif defined(TILE)
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
struct ucontext uc ;
long sp ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2011-06-09 03:36:29 +04:00
/* offset of ucontext in the kernel's sigframe structure */
# define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(struct siginfo)
2009-12-28 18:00:15 +03:00
if ( upeek ( tcp , PTREGS_OFFSET_SP , & sp ) < 0 )
return 0 ;
if ( umove ( tcp , sp + SIGFRAME_UC_OFFSET , & uc ) < 0 )
return 0 ;
Set saner MAX_ARGS (6 or 8) for X86_64 and I386
I noticed that tcp->u_args[MAX_ARGS] array is way larger than
I'd expect: for all arches except HPPA it has 32 (!) elements.
I looked at the code and so far I spotted only one abuser of
this fact: sys_sigreturn. On several arches, it saves sigset_t
into tcp->u_args[1...N] on entry and prints it on exit, a-la
memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t))
The problem here is that in glibc sigset_t is insanely large:
128 bytes, and using sizeof(sigset_t) in memcpy will overrun
&tcp->u_args[1] even with MAX_ARGS == 32:
On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes!
We may already have a bug there!
This commit changes the code to save NSIG / 8 bytes only.
NSIG can't ever be > 256, and in practice is <= 129,
thus NSIG / 8 is <= 16 bytes == 4 32-bit words,
and even MAX_ARGS == 5 should be enough for saving signal masks.
* defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8
for FreeBSD and to 6 for everyone else. Add comment about current
state of needed MAX_ARGS.
* signal.c: Add comment about size of sigset_t.
(sprintsigmask): Reduce static string buffer from 8k to 2k.
(sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes,
not sizeof(sigset_t) bytes.
* linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7.
* linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
sigemptyset ( & sigm ) ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
memcpy ( & sigm , & uc . uc_sigmask , NSIG / 8 ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
2009-12-28 18:00:15 +03:00
}
return 0 ;
2010-07-06 16:21:07 +04:00
# elif defined(MICROBLAZE)
/* TODO: Verify that this is correct... */
if ( entering ( tcp ) ) {
2011-06-09 03:36:29 +04:00
struct sigcontext sc ;
2010-07-06 16:21:07 +04:00
long sp ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
sigset_t sigm ;
2010-07-06 16:21:07 +04:00
/* Read r1, the stack pointer. */
if ( upeek ( tcp , 1 * 4 , & sp ) < 0 )
return 0 ;
if ( umove ( tcp , sp , & sc ) < 0 )
return 0 ;
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
long_to_sigset ( sc . oldmask , & sigm ) ;
2012-01-17 20:56:44 +04:00
tprints ( sprintsigmask ( " ) (mask " , & sigm , 0 ) ) ;
2010-07-06 16:21:07 +04:00
}
return 0 ;
2001-03-27 16:17:16 +04:00
# else
2002-09-23 19:41:01 +04:00
# warning No sys_sigreturn() for this architecture
# warning (no problem, just a reminder :-)
2001-03-27 16:17:16 +04:00
return 0 ;
2009-02-25 20:08:40 +03:00
# endif
1999-02-19 03:21:36 +03:00
}
int
2011-05-30 16:00:14 +04:00
sys_siggetmask ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( exiting ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_rval , & sigm ) ;
tcp - > auxstr = sprintsigmask ( " mask " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
}
return RVAL_HEX | RVAL_STR ;
}
int
Remove dead code
* defs.h (tv_tv): Remove.
* net.c (sys_xsetsockaddr): Remove commented out dead code.
* process.c (setarg, sys_execv, sys_execve, struct_user_offsets):
Likewise.
* signal.c (sys_sigsuspend): Likewise.
* strace.c (reaper, trace): Likewise.
* stream.c (internal_stream_ioctl): Likewise.
* syscall.c (trace_syscall): Likewise.
* term.c (term_ioctl): Likewise.
* util.c (tv_tv, umoven, uload, getpc, fixvfork, setbpt, clearbpt):
Likewise.
2010-01-01 01:50:49 +03:00
sys_sigsuspend ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( entering ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 2 ] , & sigm ) ;
printsigmask ( & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2012-02-25 05:38:52 +04:00
# if !defined SS_ONSTACK
1999-02-19 03:21:36 +03:00
# define SS_ONSTACK 1
# define SS_DISABLE 2
# if __GLIBC_MINOR__ == 0
typedef struct
{
__ptr_t ss_sp ;
int ss_flags ;
size_t ss_size ;
} stack_t ;
# endif
# endif
2004-09-04 07:39:20 +04:00
static const struct xlat sigaltstack_flags [ ] = {
1999-02-19 03:21:36 +03:00
{ SS_ONSTACK , " SS_ONSTACK " } ,
{ SS_DISABLE , " SS_DISABLE " } ,
{ 0 , NULL } ,
} ;
static int
2011-05-30 16:00:14 +04:00
print_stack_t ( struct tcb * tcp , unsigned long addr )
1999-02-19 03:21:36 +03:00
{
stack_t ss ;
if ( umove ( tcp , addr , & ss ) < 0 )
return - 1 ;
tprintf ( " {ss_sp=%#lx, ss_flags= " , ( unsigned long ) ss . ss_sp ) ;
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 ( sigaltstack_flags , ss . ss_flags , " SS_??? " ) ;
1999-02-19 03:21:36 +03:00
tprintf ( " , ss_size=%lu} " , ( unsigned long ) ss . ss_size ) ;
return 0 ;
}
int
2011-05-30 16:00:14 +04:00
sys_sigaltstack ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( entering ( tcp ) ) {
if ( tcp - > u_arg [ 0 ] = = 0 )
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
1999-02-19 03:21:36 +03:00
else if ( print_stack_t ( tcp , tcp - > u_arg [ 0 ] ) < 0 )
return - 1 ;
}
else {
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
if ( tcp - > u_arg [ 1 ] = = 0 )
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
1999-02-19 03:21:36 +03:00
else if ( print_stack_t ( tcp , tcp - > u_arg [ 1 ] ) < 0 )
return - 1 ;
}
return 0 ;
}
# ifdef HAVE_SIGACTION
int
2011-05-30 16:00:14 +04:00
sys_sigprocmask ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
# ifdef ALPHA
if ( entering ( tcp ) ) {
printxval ( sigprocmaskcmds , tcp - > u_arg [ 0 ] , " SIG_??? " ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-04-06 05:19:39 +04:00
printsigmask ( tcp - > u_arg [ 1 ] , 0 ) ;
1999-02-19 03:21:36 +03:00
}
else if ( ! syserror ( tcp ) ) {
1999-04-06 05:19:39 +04:00
tcp - > auxstr = sprintsigmask ( " old mask " , tcp - > u_rval , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_HEX | RVAL_STR ;
}
# else /* !ALPHA */
if ( entering ( tcp ) ) {
printxval ( sigprocmaskcmds , tcp - > u_arg [ 0 ] , " SIG_??? " ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2006-10-13 Ulrich Drepper <drepper@redhat.com>
Bernhard Kaindl <bk@suse.de>
Dmitry V. Levin <ldv@altlinux.org>
Michael Holzheu <holzheu@de.ibm.com>
Add hooks for new syscalls. Add decoders for *at, inotify*,
pselect6, ppoll and unshare syscalls.
* defs.h: Declare print_sigset.
* desc.c (sys_pselect6): New function.
* file.c (decode_open, decode_access, decode_mkdir,
decode_readlink, decode_chmod, decode_utimes, decode_mknod):
New functions.
(sys_open, sys_access, sys_mkdir, sys_readlink, sys_chmod,
sys_utimes, sys_mknod): Use them.
[LINUX] (fstatatflags, unlinkatflags, inotify_modes): New
variables.
[LINUX] (print_dirfd, sys_openat, sys_faccessat,
sys_newfstatat, sys_mkdirat, sys_linkat, sys_unlinkat,
sys_symlinkat, sys_readlinkat, sys_renameat, sys_fchownat,
sys_fchmodat, sys_futimesat, sys_mknodat, sys_inotify_add_watch,
sys_inotify_rm_watch): New functions.
* process.c [LINUX] (sys_unshare): New function.
* signal.c (print_sigset): New function.
(sys_sigprocmask): Use it.
* stream.c (decode_poll): New function.
(sys_poll): Use it.
[LINUX] (sys_ppoll): New function.
* linux/syscall.h: Delcare new syscall handlers.
* linux/syscallent.h: Hook up new syscalls.
* linux/alpha/syscallent.h: Likewise.
* linux/hppa/syscallent.h: Likewise.
* linux/ia64/syscallent.h: Likewise.
* linux/mips/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/sparc64/syscallent.h: Likewise.
* linux/x86_64/syscallent.h: Likewise.
Fixes RH#178633.
2006-10-14 00:25:12 +04:00
print_sigset ( tcp , tcp - > u_arg [ 1 ] , 0 ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
}
else {
if ( ! tcp - > u_arg [ 2 ] )
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
1999-02-19 03:21:36 +03:00
else if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 2 ] ) ;
else
2006-10-13 Ulrich Drepper <drepper@redhat.com>
Bernhard Kaindl <bk@suse.de>
Dmitry V. Levin <ldv@altlinux.org>
Michael Holzheu <holzheu@de.ibm.com>
Add hooks for new syscalls. Add decoders for *at, inotify*,
pselect6, ppoll and unshare syscalls.
* defs.h: Declare print_sigset.
* desc.c (sys_pselect6): New function.
* file.c (decode_open, decode_access, decode_mkdir,
decode_readlink, decode_chmod, decode_utimes, decode_mknod):
New functions.
(sys_open, sys_access, sys_mkdir, sys_readlink, sys_chmod,
sys_utimes, sys_mknod): Use them.
[LINUX] (fstatatflags, unlinkatflags, inotify_modes): New
variables.
[LINUX] (print_dirfd, sys_openat, sys_faccessat,
sys_newfstatat, sys_mkdirat, sys_linkat, sys_unlinkat,
sys_symlinkat, sys_readlinkat, sys_renameat, sys_fchownat,
sys_fchmodat, sys_futimesat, sys_mknodat, sys_inotify_add_watch,
sys_inotify_rm_watch): New functions.
* process.c [LINUX] (sys_unshare): New function.
* signal.c (print_sigset): New function.
(sys_sigprocmask): Use it.
* stream.c (decode_poll): New function.
(sys_poll): Use it.
[LINUX] (sys_ppoll): New function.
* linux/syscall.h: Delcare new syscall handlers.
* linux/syscallent.h: Hook up new syscalls.
* linux/alpha/syscallent.h: Likewise.
* linux/hppa/syscallent.h: Likewise.
* linux/ia64/syscallent.h: Likewise.
* linux/mips/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/sparc64/syscallent.h: Likewise.
* linux/x86_64/syscallent.h: Likewise.
Fixes RH#178633.
2006-10-14 00:25:12 +04:00
print_sigset ( tcp , tcp - > u_arg [ 2 ] , 0 ) ;
1999-02-19 03:21:36 +03:00
}
# endif /* !ALPHA */
return 0 ;
}
# endif /* HAVE_SIGACTION */
int
2011-05-30 16:00:14 +04:00
sys_kill ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( entering ( tcp ) ) {
2008-05-20 05:43:09 +04:00
long pid = tcp - > u_arg [ 0 ] ;
2011-08-21 19:26:55 +04:00
# if SUPPORTED_PERSONALITIES > 1
/* Sign-extend a 32-bit value when that's what it is. */
2008-05-20 05:43:09 +04:00
if ( personality_wordsize [ current_personality ] < sizeof pid )
pid = ( long ) ( int ) pid ;
2011-08-21 19:26:55 +04:00
# endif
2008-05-20 05:43:09 +04:00
tprintf ( " %ld, %s " , pid , signame ( tcp - > u_arg [ 1 ] ) ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2003-07-09 13:47:49 +04:00
int
2011-05-30 16:00:14 +04:00
sys_tgkill ( struct tcb * tcp )
2003-07-09 13:47:49 +04:00
{
if ( entering ( tcp ) ) {
tprintf ( " %ld, %ld, %s " ,
tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] , signame ( tcp - > u_arg [ 2 ] ) ) ;
}
return 0 ;
}
1999-02-19 03:21:36 +03:00
int
2011-05-30 16:00:14 +04:00
sys_sigpending ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
sigset_t sigset ;
if ( exiting ( tcp ) ) {
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset ( tcp , tcp - > u_arg [ 0 ] , & sigset ) < 0 )
2011-09-01 12:00:28 +04:00
tprints ( " [?] " ) ;
1999-02-19 03:21:36 +03:00
else
1999-11-26 13:12:59 +03:00
printsigmask ( & sigset , 0 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2011-05-30 16:00:14 +04:00
int
sys_rt_sigprocmask ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
sigset_t sigset ;
1999-04-06 05:19:39 +04:00
/* Note: arg[3] is the length of the sigset. */
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
printxval ( sigprocmaskcmds , tcp - > u_arg [ 0 ] , " SIG_??? " ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
if ( ! tcp - > u_arg [ 1 ] )
2011-09-01 12:00:28 +04:00
tprints ( " NULL, " ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset_len ( tcp , tcp - > u_arg [ 1 ] , & sigset , tcp - > u_arg [ 3 ] ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx, " , tcp - > u_arg [ 1 ] ) ;
else {
1999-04-06 05:19:39 +04:00
printsigmask ( & sigset , 1 ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
}
}
else {
if ( ! tcp - > u_arg [ 2 ] )
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
1999-02-19 03:21:36 +03:00
else if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 2 ] ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset_len ( tcp , tcp - > u_arg [ 2 ] , & sigset , tcp - > u_arg [ 3 ] ) < 0 )
2011-09-01 12:00:28 +04:00
tprints ( " [?] " ) ;
1999-02-19 03:21:36 +03:00
else
1999-04-06 05:19:39 +04:00
printsigmask ( & sigset , 1 ) ;
1999-03-30 03:33:35 +04:00
tprintf ( " , %lu " , tcp - > u_arg [ 3 ] ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
/* Structure describing the action to be taken when a signal arrives. */
struct new_sigaction
{
2009-04-15 17:22:59 +04:00
__sighandler_t __sa_handler ;
1999-02-19 03:21:36 +03:00
unsigned long sa_flags ;
void ( * sa_restorer ) ( void ) ;
2009-04-15 17:22:59 +04:00
/* Kernel treats sa_mask as an array of longs. */
unsigned long sa_mask [ NSIG / sizeof ( long ) ? NSIG / sizeof ( long ) : 1 ] ;
} ;
/* Same for i386-on-x86_64 and similar cases */
struct new_sigaction32
{
uint32_t __sa_handler ;
uint32_t sa_flags ;
uint32_t sa_restorer ;
uint32_t sa_mask [ 2 * ( NSIG / sizeof ( long ) ? NSIG / sizeof ( long ) : 1 ) ] ;
1999-02-19 03:21:36 +03:00
} ;
2008-08-20 05:59:40 +04:00
int
2009-04-14 16:51:00 +04:00
sys_rt_sigaction ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
struct new_sigaction sa ;
sigset_t sigset ;
long addr ;
2009-04-15 17:22:59 +04:00
int r ;
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
addr = tcp - > u_arg [ 1 ] ;
} else
addr = tcp - > u_arg [ 2 ] ;
2009-04-15 17:22:59 +04:00
if ( addr = = 0 ) {
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
2009-04-15 17:22:59 +04:00
goto after_sa ;
}
if ( ! verbose ( tcp ) ) {
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , addr ) ;
2009-04-15 17:22:59 +04:00
goto after_sa ;
}
# if SUPPORTED_PERSONALITIES > 1
if ( personality_wordsize [ current_personality ] ! = sizeof ( sa . sa_flags )
& & personality_wordsize [ current_personality ] = = 4
) {
struct new_sigaction32 sa32 ;
r = umove ( tcp , addr , & sa32 ) ;
if ( r > = 0 ) {
memset ( & sa , 0 , sizeof ( sa ) ) ;
sa . __sa_handler = ( void * ) ( unsigned long ) sa32 . __sa_handler ;
sa . sa_flags = sa32 . sa_flags ;
sa . sa_restorer = ( void * ) ( unsigned long ) sa32 . sa_restorer ;
/* Kernel treats sa_mask as an array of longs.
* For 32 - bit process , " long " is uint32_t , thus , for example ,
* 32 th bit in sa_mask will end up as bit 0 in sa_mask [ 1 ] .
* But for ( 64 - bit ) kernel , 32 th bit in sa_mask is
* 32 th bit in 0 th ( 64 - bit ) long !
* For little - endian , it ' s the same .
* For big - endian , we swap 32 - bit words .
*/
sa . sa_mask [ 0 ] = sa32 . sa_mask [ 0 ] + ( ( long ) ( sa32 . sa_mask [ 1 ] ) < < 32 ) ;
}
} else
# endif
{
r = umove ( tcp , addr , & sa ) ;
}
if ( r < 0 ) {
2011-09-01 12:00:28 +04:00
tprints ( " {...} " ) ;
2009-04-15 17:22:59 +04:00
goto after_sa ;
}
2009-09-09 22:13:19 +04:00
/* Architectures using function pointers, like
* hppa , may need to manipulate the function pointer
* to compute the result of a comparison . However ,
* the SA_HANDLER function pointer exists only in
* the address space of the traced process , and can ' t
* be manipulated by strace . In order to prevent the
* compiler from generating code to manipulate
* SA_HANDLER we cast the function pointers to long . */
if ( ( long ) sa . __sa_handler = = ( long ) SIG_ERR )
2011-09-01 12:00:28 +04:00
tprints ( " {SIG_ERR, " ) ;
2009-09-09 22:13:19 +04:00
else if ( ( long ) sa . __sa_handler = = ( long ) SIG_DFL )
2011-09-01 12:00:28 +04:00
tprints ( " {SIG_DFL, " ) ;
2009-09-09 22:13:19 +04:00
else if ( ( long ) sa . __sa_handler = = ( long ) SIG_IGN )
2011-09-01 12:00:28 +04:00
tprints ( " {SIG_IGN, " ) ;
2009-04-15 17:22:59 +04:00
else
tprintf ( " {%#lx, " , ( long ) sa . __sa_handler ) ;
/* Questionable code below.
* Kernel won ' t handle sys_rt_sigaction
* with wrong sigset size ( just returns EINVAL )
* therefore tcp - > u_arg [ 3 ( 4 ) ] _must_ be NSIG / 8 here ,
* and we always use smaller memcpy . */
sigemptyset ( & sigset ) ;
1999-06-03 18:21:07 +04:00
# ifdef LINUXSPARC
2009-04-15 17:22:59 +04:00
if ( tcp - > u_arg [ 4 ] < = sizeof ( sigset ) )
memcpy ( & sigset , & sa . sa_mask , tcp - > u_arg [ 4 ] ) ;
1999-06-03 18:21:07 +04:00
# else
2009-04-15 17:22:59 +04:00
if ( tcp - > u_arg [ 3 ] < = sizeof ( sigset ) )
memcpy ( & sigset , & sa . sa_mask , tcp - > u_arg [ 3 ] ) ;
1999-06-03 18:21:07 +04:00
# endif
2009-04-15 17:22:59 +04:00
else
memcpy ( & sigset , & sa . sa_mask , sizeof ( sigset ) ) ;
printsigmask ( & sigset , 1 ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2009-04-15 17:22:59 +04:00
printflags ( sigact_flags , sa . sa_flags , " SA_??? " ) ;
2002-12-16 02:58:41 +03:00
# ifdef SA_RESTORER
2009-04-15 17:22:59 +04:00
if ( sa . sa_flags & SA_RESTORER )
tprintf ( " , %p " , sa . sa_restorer ) ;
2002-12-16 02:58:41 +03:00
# endif
2011-09-01 12:00:28 +04:00
tprints ( " } " ) ;
2009-04-15 17:22:59 +04:00
after_sa :
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) )
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
else
1999-06-03 18:21:07 +04:00
# ifdef LINUXSPARC
tprintf ( " , %#lx, %lu " , tcp - > u_arg [ 3 ] , tcp - > u_arg [ 4 ] ) ;
# elif defined(ALPHA)
tprintf ( " , %lu, %#lx " , tcp - > u_arg [ 3 ] , tcp - > u_arg [ 4 ] ) ;
# else
2009-04-15 17:22:59 +04:00
tprintf ( " , %lu " , tcp - > u_arg [ 3 ] ) ;
1999-06-03 18:21:07 +04:00
# endif
1999-02-19 03:21:36 +03:00
return 0 ;
}
2009-04-14 16:51:00 +04:00
int
sys_rt_sigpending ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
sigset_t sigset ;
if ( exiting ( tcp ) ) {
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset_len ( tcp , tcp - > u_arg [ 0 ] ,
& sigset , tcp - > u_arg [ 1 ] ) < 0 )
2011-09-01 12:00:28 +04:00
tprints ( " [?] " ) ;
1999-02-19 03:21:36 +03:00
else
1999-11-26 13:12:59 +03:00
printsigmask ( & sigset , 1 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2009-04-14 16:51:00 +04:00
int
sys_rt_sigsuspend ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( entering ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
if ( copy_sigset_len ( tcp , tcp - > u_arg [ 0 ] , & sigm , tcp - > u_arg [ 1 ] ) < 0 )
2011-09-01 12:00:28 +04:00
tprints ( " [?] " ) ;
1999-04-06 05:19:39 +04:00
else
printsigmask ( & sigm , 1 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2009-04-14 16:51:00 +04:00
2012-03-13 19:51:13 +04:00
static void
print_sigqueueinfo ( struct tcb * tcp , int sig , unsigned long uinfo )
{
siginfo_t si ;
printsignal ( sig ) ;
tprints ( " , " ) ;
if ( umove ( tcp , uinfo , & si ) < 0 )
tprintf ( " %#lx " , uinfo ) ;
else
printsiginfo ( & si , verbose ( tcp ) ) ;
}
2009-04-14 16:51:00 +04:00
int
sys_rt_sigqueueinfo ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( entering ( tcp ) ) {
tprintf ( " %lu, " , tcp - > u_arg [ 0 ] ) ;
2012-03-13 19:51:13 +04:00
print_sigqueueinfo ( tcp , tcp - > u_arg [ 1 ] , tcp - > u_arg [ 2 ] ) ;
}
return 0 ;
}
int
sys_rt_tgsigqueueinfo ( struct tcb * tcp )
{
if ( entering ( tcp ) ) {
tprintf ( " %lu, %lu, " , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] ) ;
print_sigqueueinfo ( tcp , tcp - > u_arg [ 2 ] , tcp - > u_arg [ 3 ] ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2009-04-14 16:51:00 +04:00
int sys_rt_sigtimedwait ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
if ( entering ( tcp ) ) {
sigset_t sigset ;
2002-12-17 08:10:37 +03:00
if ( copy_sigset_len ( tcp , tcp - > u_arg [ 0 ] ,
1999-04-06 05:19:39 +04:00
& sigset , tcp - > u_arg [ 3 ] ) < 0 )
2011-09-01 12:00:28 +04:00
tprints ( " [?] " ) ;
1999-02-19 03:21:36 +03:00
else
1999-11-26 13:12:59 +03:00
printsigmask ( & sigset , 1 ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2009-04-15 17:31:59 +04:00
/* This is the only "return" parameter, */
if ( tcp - > u_arg [ 1 ] ! = 0 )
return 0 ;
/* ... if it's NULL, can decode all on entry */
2011-09-01 12:00:28 +04:00
tprints ( " NULL, " ) ;
1999-02-19 03:21:36 +03:00
}
2009-04-15 17:31:59 +04:00
else if ( tcp - > u_arg [ 1 ] ! = 0 ) {
/* syscall exit, and u_arg[1] wasn't NULL */
1999-02-19 03:21:36 +03:00
if ( syserror ( tcp ) )
2009-04-15 17:31:59 +04:00
tprintf ( " %#lx, " , tcp - > u_arg [ 1 ] ) ;
1999-02-19 03:21:36 +03:00
else {
siginfo_t si ;
if ( umove ( tcp , tcp - > u_arg [ 1 ] , & si ) < 0 )
2009-04-15 17:31:59 +04:00
tprintf ( " %#lx, " , tcp - > u_arg [ 1 ] ) ;
else {
2009-01-13 21:30:55 +03:00
printsiginfo ( & si , verbose ( tcp ) ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2009-04-15 17:31:59 +04:00
}
1999-02-19 03:21:36 +03:00
}
}
2009-04-15 17:31:59 +04:00
else {
/* syscall exit, and u_arg[1] was NULL */
return 0 ;
}
print_timespec ( tcp , tcp - > u_arg [ 2 ] ) ;
tprintf ( " , %d " , ( int ) tcp - > u_arg [ 3 ] ) ;
1999-02-19 03:21:36 +03:00
return 0 ;
} ;
2006-01-13 01:34:50 +03:00
int
2009-04-14 16:51:00 +04:00
sys_restart_syscall ( struct tcb * tcp )
2006-01-13 01:34:50 +03:00
{
if ( entering ( tcp ) )
2011-09-01 12:00:28 +04:00
tprints ( " <... resuming interrupted call ...> " ) ;
2006-01-13 01:34:50 +03:00
return 0 ;
}
2008-10-23 Dmitry V. Levin <ldv@altlinux.org>
Implement parsers for new linux syscalls.
* desc.c (do_dup2, [LINUX] sys_dup3): New functions.
(sys_dup2): Use do_dup2.
[LINUX] (sys_epoll_create1): New function.
[LINUX] (do_eventfd, sys_eventfd2): New functions.
[LINUX] (sys_eventfd): Use do_eventfd.
* net.c (do_pipe, [LINUX] sys_pipe2): New functions.
(sys_pipe): Use do_pipe.
* signal.c [LINUX] (do_signalfd, sys_signalfd4): New functions.
[LINUX] (sys_signalfd): Use do_signalfd.
* linux/syscall.h: Declare new sys_* functions.
* linux/syscallent.h: Hook up signalfd4, eventfd2, epoll_create1,
dup3, pipe2, inotify_init1.
* linux/x86_64/syscallent.h: Hook up paccept, signalfd4, eventfd2,
epoll_create1, dup3, pipe2, inotify_init1.
2008-11-11 01:53:02 +03:00
static int
do_signalfd ( struct tcb * tcp , int flags_arg )
2007-08-02 05:15:59 +04:00
{
if ( entering ( tcp ) ) {
Fix decoding of file descriptors
* defs.h (printfd): New function prototype.
* util.c (printfd): New function.
* file.c (print_dirfd): Update prototype to use printfd().
(sys_openat, sys_faccessat, sys_newfstatat, sys_mkdirat, sys_linkat,
sys_unlinkat, sys_readlinkat, sys_renameat, sys_fchownat, sys_fchmodat,
sys_futimesat, sys_utimensat, sys_mknodat): Update use of print_dirfd().
(sys_lseek, sys_llseek, sys_readahead, sys_ftruncate, sys_ftruncate64,
sys_fstat, sys_fstat64, sys_oldfstat, sys_fstatfs, sys_fstatfs64,
sys_fchdir, sys_fchroot, sys_linkat, sys_fchown, sys_fchmod, sys_fsync,
sys_readdir, sys_getdents, sys_getdirentries, sys_fsetxattr,
sys_fgetxattr, sys_flistxattr, sys_fremovexattr, sys_fadvise64,
sys_fadvise64_64, sys_inotify_add_watch, sys_inotify_rm_watch,
sys_fallocate): Use printfd() for decoding of file descriptors.
* desc.c (sys_fcntl, sys_flock, sys_close, sys_dup, do_dup2,
decode_select, sys_epoll_ctl, epoll_wait_common): Use printfd() for
decoding of file descriptors.
* io.c (sys_read, sys_write, sys_readv, sys_writev, sys_pread,
sys_pwrite, sys_sendfile, sys_sendfile64, sys_pread64, sys_pwrite64,
sys_ioctl): Likewise.
* mem.c (print_mmap, sys_mmap64): Likewise.
* signal.c (do_signalfd): Likewise.
* stream.c (decode_poll): Likewise.
* time.c (sys_timerfd_settime, sys_timerfd_gettime): Likewise.
Based on patch from Grant Edwards <grant.b.edwards@gmail.com>.
2011-03-04 05:08:02 +03:00
printfd ( tcp , tcp - > u_arg [ 0 ] ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2007-08-02 05:15:59 +04:00
print_sigset ( tcp , tcp - > u_arg [ 1 ] , 1 ) ;
2009-10-05 17:45:19 +04:00
tprintf ( " , %lu " , tcp - > u_arg [ 2 ] ) ;
2008-10-23 Dmitry V. Levin <ldv@altlinux.org>
Implement parsers for new linux syscalls.
* desc.c (do_dup2, [LINUX] sys_dup3): New functions.
(sys_dup2): Use do_dup2.
[LINUX] (sys_epoll_create1): New function.
[LINUX] (do_eventfd, sys_eventfd2): New functions.
[LINUX] (sys_eventfd): Use do_eventfd.
* net.c (do_pipe, [LINUX] sys_pipe2): New functions.
(sys_pipe): Use do_pipe.
* signal.c [LINUX] (do_signalfd, sys_signalfd4): New functions.
[LINUX] (sys_signalfd): Use do_signalfd.
* linux/syscall.h: Declare new sys_* functions.
* linux/syscallent.h: Hook up signalfd4, eventfd2, epoll_create1,
dup3, pipe2, inotify_init1.
* linux/x86_64/syscallent.h: Hook up paccept, signalfd4, eventfd2,
epoll_create1, dup3, pipe2, inotify_init1.
2008-11-11 01:53:02 +03:00
if ( flags_arg > = 0 ) {
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2008-10-23 Dmitry V. Levin <ldv@altlinux.org>
Implement parsers for new linux syscalls.
* desc.c (do_dup2, [LINUX] sys_dup3): New functions.
(sys_dup2): Use do_dup2.
[LINUX] (sys_epoll_create1): New function.
[LINUX] (do_eventfd, sys_eventfd2): New functions.
[LINUX] (sys_eventfd): Use do_eventfd.
* net.c (do_pipe, [LINUX] sys_pipe2): New functions.
(sys_pipe): Use do_pipe.
* signal.c [LINUX] (do_signalfd, sys_signalfd4): New functions.
[LINUX] (sys_signalfd): Use do_signalfd.
* linux/syscall.h: Declare new sys_* functions.
* linux/syscallent.h: Hook up signalfd4, eventfd2, epoll_create1,
dup3, pipe2, inotify_init1.
* linux/x86_64/syscallent.h: Hook up paccept, signalfd4, eventfd2,
epoll_create1, dup3, pipe2, inotify_init1.
2008-11-11 01:53:02 +03:00
printflags ( open_mode_flags , tcp - > u_arg [ flags_arg ] , " O_??? " ) ;
}
2007-08-02 05:15:59 +04:00
}
return 0 ;
}
2008-10-23 Dmitry V. Levin <ldv@altlinux.org>
Implement parsers for new linux syscalls.
* desc.c (do_dup2, [LINUX] sys_dup3): New functions.
(sys_dup2): Use do_dup2.
[LINUX] (sys_epoll_create1): New function.
[LINUX] (do_eventfd, sys_eventfd2): New functions.
[LINUX] (sys_eventfd): Use do_eventfd.
* net.c (do_pipe, [LINUX] sys_pipe2): New functions.
(sys_pipe): Use do_pipe.
* signal.c [LINUX] (do_signalfd, sys_signalfd4): New functions.
[LINUX] (sys_signalfd): Use do_signalfd.
* linux/syscall.h: Declare new sys_* functions.
* linux/syscallent.h: Hook up signalfd4, eventfd2, epoll_create1,
dup3, pipe2, inotify_init1.
* linux/x86_64/syscallent.h: Hook up paccept, signalfd4, eventfd2,
epoll_create1, dup3, pipe2, inotify_init1.
2008-11-11 01:53:02 +03:00
int
sys_signalfd ( struct tcb * tcp )
{
return do_signalfd ( tcp , - 1 ) ;
}
int
sys_signalfd4 ( struct tcb * tcp )
{
return do_signalfd ( tcp , 3 ) ;
}