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 .
*/
# include "defs.h"
# 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(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
Add x32 support to strace
X32 support is added to Linux kernel 3.4. In a nutshell, x32 is x86-64 with
32bit pointers. At system call level, x32 is also identical to x86-64,
as shown by many changes like "defined(X86_64) || defined(X32)". The
main differerence bewteen x32 and x86-64 is off_t in x32 is long long
instead of long.
This patch adds x32 support to strace. Tested on Linux/x32.
* configure.ac: Support X32.
* defs.h: Set SUPPORTED_PERSONALITIES to 3 for X86_64,
Set PERSONALITY2_WORDSIZE to 4 for X86_64.
Add tcb::ext_arg for X32.
* file.c (stat): New for X32.
(sys_lseek): Use 64-bit version for X32.
(printstat64): Check current_personality != 1 for X86_64.
* ipc.c (indirect_ipccall): Check current_personality == 1
for X86_64.
* mem.c (sys_mmap64): Also use tcp->u_arg for X32. Print NULL
for zero address. Call printllval for offset for X32.
* pathtrace.c (pathtrace_match): Don't check sys_old_mmap for
X32.
* process.c (ARG_FLAGS): Defined for X32.
(ARG_STACK): Likewise.
(ARG_PTID): Likewise.
(change_syscall): Handle X32.
(struct_user_offsets): Support X32.
(sys_arch_prctl): Likewise.
* signal.c: Include <asm/sigcontext.h> for X32.
(SA_RESTORER): Also define for X32.
* syscall.c (update_personality): Support X32 for X86_64.
(is_restart_error): Likewise.
(syscall_fixup_on_sysenter): Likewise.
(get_syscall_args): Likewise.
(get_syscall_result): Likewise.
(get_error): Likewise.
(__X32_SYSCALL_BIT): Define if not defined.
(__X32_SYSCALL_MASK): Likewise.
(get_scno): Check DS register value for X32. Use
__X32_SYSCALL_MASK on X32 system calls.
* util.c (printllval): Use ext_arg for X32.
(printcall): Support X32.
(change_syscall): Likewise.
(arg0_offset): Likewise.
(arg1_offset): Likewise.
* Makefile.am (EXTRA_DIST): Add linux/x32/errnoent.h,
linux/x32/ioctlent.h.in, linux/x32/signalent.h,
linux/x32/syscallent.h, linux/x86_64/errnoent2.h,
linux/x86_64/ioctlent2.h, linux/x86_64/signalent2.h and
linux/x86_64/syscallent2.h.
* linux/x32/errnoent.h: New.
* linux/x32/ioctlent.h.in: Likewise.
* linux/x32/signalent.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/errnoent2.h: Likewise.
* linux/x86_64/ioctlent2.h: Likewise.
* linux/x86_64/signalent2.h: Likewise.
* linux/x86_64/syscallent2.h: Likewise.
Signed-off-by: H.J. Lu <hongjiu.lu@intel.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-04-16 15:00:01 +04:00
# if !defined(IA64) && !defined(X86_64) && !defined(X32)
2012-02-25 05:38:52 +04:00
# include <asm / sigcontext.h>
2012-03-16 15:02:22 +04:00
# endif
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
Add x32 support to strace
X32 support is added to Linux kernel 3.4. In a nutshell, x32 is x86-64 with
32bit pointers. At system call level, x32 is also identical to x86-64,
as shown by many changes like "defined(X86_64) || defined(X32)". The
main differerence bewteen x32 and x86-64 is off_t in x32 is long long
instead of long.
This patch adds x32 support to strace. Tested on Linux/x32.
* configure.ac: Support X32.
* defs.h: Set SUPPORTED_PERSONALITIES to 3 for X86_64,
Set PERSONALITY2_WORDSIZE to 4 for X86_64.
Add tcb::ext_arg for X32.
* file.c (stat): New for X32.
(sys_lseek): Use 64-bit version for X32.
(printstat64): Check current_personality != 1 for X86_64.
* ipc.c (indirect_ipccall): Check current_personality == 1
for X86_64.
* mem.c (sys_mmap64): Also use tcp->u_arg for X32. Print NULL
for zero address. Call printllval for offset for X32.
* pathtrace.c (pathtrace_match): Don't check sys_old_mmap for
X32.
* process.c (ARG_FLAGS): Defined for X32.
(ARG_STACK): Likewise.
(ARG_PTID): Likewise.
(change_syscall): Handle X32.
(struct_user_offsets): Support X32.
(sys_arch_prctl): Likewise.
* signal.c: Include <asm/sigcontext.h> for X32.
(SA_RESTORER): Also define for X32.
* syscall.c (update_personality): Support X32 for X86_64.
(is_restart_error): Likewise.
(syscall_fixup_on_sysenter): Likewise.
(get_syscall_args): Likewise.
(get_syscall_result): Likewise.
(get_error): Likewise.
(__X32_SYSCALL_BIT): Define if not defined.
(__X32_SYSCALL_MASK): Likewise.
(get_scno): Check DS register value for X32. Use
__X32_SYSCALL_MASK on X32 system calls.
* util.c (printllval): Use ext_arg for X32.
(printcall): Support X32.
(change_syscall): Likewise.
(arg0_offset): Likewise.
(arg1_offset): Likewise.
* Makefile.am (EXTRA_DIST): Add linux/x32/errnoent.h,
linux/x32/ioctlent.h.in, linux/x32/signalent.h,
linux/x32/syscallent.h, linux/x86_64/errnoent2.h,
linux/x86_64/ioctlent2.h, linux/x86_64/signalent2.h and
linux/x86_64/syscallent2.h.
* linux/x32/errnoent.h: New.
* linux/x32/ioctlent.h.in: Likewise.
* linux/x32/signalent.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/errnoent2.h: Likewise.
* linux/x86_64/ioctlent2.h: Likewise.
* linux/x86_64/signalent2.h: Likewise.
* linux/x86_64/syscallent2.h: Likewise.
Signed-off-by: H.J. Lu <hongjiu.lu@intel.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-04-16 15:00:01 +04:00
# if defined I386 || defined X86_64 || defined X32
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 */
2012-03-15 20:24:49 +04:00
# endif
2011-03-11 01:18:56 +03:00
2012-03-15 20:24:49 +04:00
# ifndef SI_FROMUSER
# 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
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
2012-04-15 22:17:13 +04:00
tprintf ( " , si_utime=%llu, si_stime=%llu " ,
( unsigned long long ) sip - > si_utime ,
( unsigned long long ) sip - > si_stime ) ;
2001-10-18 19:13:53 +04:00
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 {
2013-02-08 15:59:13 +04:00
/* sa_handler may be a libc #define, need to use other name: */
void ( * __sa_handler ) ( int ) ;
1999-02-19 03:21:36 +03:00
unsigned long sa_mask ;
unsigned long sa_flags ;
void ( * sa_restorer ) ( void ) ;
} ;
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 ,
2013-02-08 15:59:13 +04:00
* the __sa_handler function pointer exists only in
2009-09-09 22:13:19 +04:00
* 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
2013-02-08 15:59:13 +04:00
* __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, " ) ;
2013-02-08 15:59:13 +04:00
else if ( ( long ) sa . __sa_handler = = ( long ) SIG_DFL )
2011-09-01 12:00:28 +04:00
tprints ( " {SIG_DFL, " ) ;
2013-02-08 15:59:13 +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
2013-02-08 15:59:13 +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 ) {
2012-03-17 07:42:07 +04:00
case ( long ) SIG_ERR :
2000-08-10 06:14:04 +04:00
tcp - > auxstr = " SIG_ERR " ; break ;
2012-03-17 07:42:07 +04:00
case ( long ) SIG_DFL :
2000-08-10 06:14:04 +04:00
tcp - > auxstr = " SIG_DFL " ; break ;
2012-03-17 07:42:07 +04:00
case ( long ) SIG_IGN :
2000-08-10 06:14:04 +04:00
tcp - > auxstr = " SIG_IGN " ; break ;
2012-03-17 07:42:07 +04:00
default :
2000-08-10 06:14:04 +04:00
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 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 ;
2013-02-06 21:24:39 +04:00
if ( umove ( tcp , arm_regs . ARM_sp , & sc ) < 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
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
}
# 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
}
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
}
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
}
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
}
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
}
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
}
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 ;
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 ;
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 ) {
2012-09-18 03:20:54 +04:00
perror_msg ( " %s " , " 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
}
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
}
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 ) {
2012-09-18 03:20:54 +04:00
perror_msg ( " %s " , " sigreturn: PTRACE_GETREGS " ) ;
2011-06-09 03:36:29 +04:00
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
}
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 ) {
2012-09-18 03:20:54 +04:00
perror_msg ( " %s " , " sigreturn: PTRACE_GETREGS " ) ;
2009-02-25 20:08:40 +03:00
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
}
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 ;
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)
Add tilegx support to strace
tilegx support has been in the kernel since 3.0.
In addition, fix some issues with the tilepro support already
present in strace, primarily the decision to use the
<asm/unistd.h> numbering space for system calls.
* defs.h [TILE]: Include <asm/ptrace.h> and provide an extern
struct pt_regs tile_regs for efficiency. Provide compat 32-bit
personality via SUPPORTED_PERSONALITIES, PERSONALITY0_WORDSIZE,
PERSONALITY1_WORDSIZE, and DEFAULT_PERSONALITY.
* linux/tile/errnoent1.h: New file, includes linux/errnoent.h.
* linux/tile/ioctlent1.h: New file, includes linux/ioctlent.h.
* linux/tile/signalent1.h: New file, includes linux/signalent.h.
* linux/tile/syscallent.h: Update with new asm-generic syscalls.
The version previously committed was the from the first tile patch
to LKML, which subsequently was changed to use <asm-generic/unistd.h>.
* linux/tile/syscallent1.h: Copy from linux/tile/syscallent.h.
* mem.c (addtileflags) [TILE]: use %ld properly for a "long" variable.
* process.c [TILE]: Choose clone arguments correctly and properly
suppress all "struct user" related offsets in user_struct_offsets.
* signal.c [TILE]: Use tile_regs not upeek.
* syscall.c (update_personality) [TILE]: Print mode.
(PT_FLAGS_COMPAT) [TILE]: Provide if not in system headers.
(tile_regs) [TILE]: Define 'struct pt_regs' variable to hold state.
(get_regs) [TILE]: use PTRACE_GETREGS to set tile_regs rather than using upeek.
(get_scno) [TILE]: Set personality.
(get_syscall_args) [TILE]: Use tile_regs.
(get_syscall_result) [TILE]: Update tile_regs.
(get_error) [TILE]: Use tile_regs.
(printcall) [TILE]: Print pc.
(arg0_offset, arg1_offset, restore_arg0, restore_arg1) [TILE]:
Properly handle tile call semantics and support tilegx.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-05 20:48:33 +04:00
if ( umove ( tcp , tile_regs . sp + SIGFRAME_UC_OFFSET , & uc ) < 0 )
2009-12-28 18:00:15 +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 , & 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
}
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
}
2012-05-15 04:13:59 +04:00
# elif defined(X86_64)
/* no need to remind */
2001-03-27 16:17:16 +04:00
# else
2012-05-15 04:13:59 +04:00
# warning No sys_sigreturn() for this architecture
# warning (no problem, just a reminder :-)
2009-02-25 20:08:40 +03:00
# endif
2012-05-15 04:13:59 +04:00
return 0 ;
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
# 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
alpha: fix decode of osf_sigprocmask
The alpha sigprocmask syscall is special in that it comes from OSF rather
than the style that everyone else uses.
Tested with this simple code:
$ cat test.c
#include <signal.h>
main() {
sigset_t set, oldset;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGHUP);
sigprocmask(SIG_SETMASK, &set, &oldset);
sigprocmask(SIG_UNBLOCK, &oldset, &set);
sleep(3);
}
$ gcc test.c && ./strace ./a.out
...
osf_sigprocmask(SIG_SETMASK, [HUP INT]) = 0 (old mask [])
osf_sigprocmask(SIG_UNBLOCK, []) = 0x3 (old mask [HUP INT])
osf_sigprocmask(SIG_BLOCK, [CHLD]) = 0x3 (old mask [HUP INT])
...
* linux/alpha/syscallent.h: Call sys_sigprocmask for osf_sigprocmask,
and change number of arguments to two.
* signal.c (sys_sigprocmask): Fix decoding of alpha osf sigprocmask.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2012-03-15 08:45:33 +04:00
sigset_t ss ;
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
alpha: fix decode of osf_sigprocmask
The alpha sigprocmask syscall is special in that it comes from OSF rather
than the style that everyone else uses.
Tested with this simple code:
$ cat test.c
#include <signal.h>
main() {
sigset_t set, oldset;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGHUP);
sigprocmask(SIG_SETMASK, &set, &oldset);
sigprocmask(SIG_UNBLOCK, &oldset, &set);
sleep(3);
}
$ gcc test.c && ./strace ./a.out
...
osf_sigprocmask(SIG_SETMASK, [HUP INT]) = 0 (old mask [])
osf_sigprocmask(SIG_UNBLOCK, []) = 0x3 (old mask [HUP INT])
osf_sigprocmask(SIG_BLOCK, [CHLD]) = 0x3 (old mask [HUP INT])
...
* linux/alpha/syscallent.h: Call sys_sigprocmask for osf_sigprocmask,
and change number of arguments to two.
* signal.c (sys_sigprocmask): Fix decoding of alpha osf sigprocmask.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2012-03-15 08:45:33 +04:00
/*
* Alpha / OSF is different : it doesn ' t pass in two pointers ,
* but rather passes in the new bitmask as an argument and
* then returns the old bitmask . This " works " because we
* only have 64 signals to worry about . If you want more ,
* use of the rt_sigprocmask syscall is required .
* Alpha :
* old = osf_sigprocmask ( how , new ) ;
* Everyone else :
* ret = sigprocmask ( how , & new , & old , . . . ) ;
*/
memcpy ( & ss , & tcp - > u_arg [ 1 ] , sizeof ( long ) ) ;
1999-02-19 03:21:36 +03:00
printxval ( sigprocmaskcmds , tcp - > u_arg [ 0 ] , " SIG_??? " ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
alpha: fix decode of osf_sigprocmask
The alpha sigprocmask syscall is special in that it comes from OSF rather
than the style that everyone else uses.
Tested with this simple code:
$ cat test.c
#include <signal.h>
main() {
sigset_t set, oldset;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGHUP);
sigprocmask(SIG_SETMASK, &set, &oldset);
sigprocmask(SIG_UNBLOCK, &oldset, &set);
sleep(3);
}
$ gcc test.c && ./strace ./a.out
...
osf_sigprocmask(SIG_SETMASK, [HUP INT]) = 0 (old mask [])
osf_sigprocmask(SIG_UNBLOCK, []) = 0x3 (old mask [HUP INT])
osf_sigprocmask(SIG_BLOCK, [CHLD]) = 0x3 (old mask [HUP INT])
...
* linux/alpha/syscallent.h: Call sys_sigprocmask for osf_sigprocmask,
and change number of arguments to two.
* signal.c (sys_sigprocmask): Fix decoding of alpha osf sigprocmask.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2012-03-15 08:45:33 +04:00
printsigmask ( & ss , 0 ) ;
1999-02-19 03:21:36 +03:00
}
else if ( ! syserror ( tcp ) ) {
alpha: fix decode of osf_sigprocmask
The alpha sigprocmask syscall is special in that it comes from OSF rather
than the style that everyone else uses.
Tested with this simple code:
$ cat test.c
#include <signal.h>
main() {
sigset_t set, oldset;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGHUP);
sigprocmask(SIG_SETMASK, &set, &oldset);
sigprocmask(SIG_UNBLOCK, &oldset, &set);
sleep(3);
}
$ gcc test.c && ./strace ./a.out
...
osf_sigprocmask(SIG_SETMASK, [HUP INT]) = 0 (old mask [])
osf_sigprocmask(SIG_UNBLOCK, []) = 0x3 (old mask [HUP INT])
osf_sigprocmask(SIG_BLOCK, [CHLD]) = 0x3 (old mask [HUP INT])
...
* linux/alpha/syscallent.h: Call sys_sigprocmask for osf_sigprocmask,
and change number of arguments to two.
* signal.c (sys_sigprocmask): Fix decoding of alpha osf sigprocmask.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2012-03-15 08:45:33 +04:00
memcpy ( & ss , & tcp - > u_rval , sizeof ( long ) ) ;
tcp - > auxstr = sprintsigmask ( " old mask " , & ss , 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. */
2012-03-19 12:36:42 +04:00
if ( current_wordsize < sizeof pid )
2008-05-20 05:43:09 +04:00
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
{
2013-02-08 15:59:13 +04:00
/* sa_handler may be a libc #define, need to use other name: */
void ( * __sa_handler ) ( int ) ;
1999-02-19 03:21:36 +03:00
unsigned long sa_flags ;
2013-02-08 15:59:13 +04:00
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
2012-03-16 00:42:46 +04:00
# if SIZEOF_LONG > 4
2012-03-19 12:36:42 +04:00
if ( current_wordsize ! = sizeof ( sa . sa_flags ) & & current_wordsize = = 4 ) {
2009-04-15 17:22:59 +04:00
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
2012-03-16 00:42:46 +04:00
# endif
2009-04-15 17:22:59 +04:00
# 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 ,
2013-02-08 15:59:13 +04:00
* the __sa_handler function pointer exists only in
2009-09-09 22:13:19 +04:00
* 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
2013-02-08 15:59:13 +04:00
* __sa_handler we cast the function pointers to long . */
2009-09-09 22:13:19 +04:00
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 ) ;
}