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>
2014-10-20 03:02:48 +04:00
# endif
# ifdef 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
2013-09-24 21:04:32 +04:00
# ifdef HAVE_STRUCT_PTRACE_PEEKSIGINFO_ARGS
# define ptrace_peeksiginfo_args XXX_ptrace_peeksiginfo_args
# endif
2012-02-25 05:38:52 +04:00
# include <linux / ptrace.h>
2013-09-24 21:04:32 +04:00
# undef ptrace_peeksiginfo_args
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 */
2013-07-16 14:06:25 +04:00
# if defined M68K && !defined HAVE_STRUCT_SIGCONTEXT
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 ;
} ;
2013-07-16 14:06:25 +04:00
# endif /* M68K */
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
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
# elif NSIG < 32
# error: 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
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 . */
2014-02-08 04:26:06 +04:00
# ifndef SA_RESTORER
# ifdef ASM_SA_RESTORER
# define SA_RESTORER ASM_SA_RESTORER
2002-12-16 02:58:41 +03:00
# endif
# endif
2014-08-14 08:30:24 +04:00
/* Some arches define this in their headers, but don't actually have it,
2014-08-09 17:04:18 +04:00
so we have to delete the define . */
2014-08-14 08:30:24 +04:00
# if defined(HPPA) || defined(IA64)
2014-08-09 17:04:18 +04:00
# undef SA_RESTORER
# endif
2014-04-26 03:30:54 +04:00
# include "xlat/sigact_flags.h"
# include "xlat/sigprocmaskcmds.h"
1999-02-19 03:21:36 +03:00
# 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 *
2014-09-10 17:46:04 +04:00
signame ( const int sig )
1999-03-30 03:23:13 +04:00
{
2014-09-10 17:46:04 +04:00
static char buf [ sizeof ( " SIGRT_%u " ) + sizeof ( int ) * 3 ] ;
2011-08-18 14:48:56 +04:00
2014-09-10 17:46:04 +04:00
if ( sig > = 0 ) {
const unsigned int s = sig ;
if ( s < nsignals )
return signalent [ s ] ;
1999-03-30 03:23:13 +04:00
# ifdef SIGRTMIN
2014-09-10 17:46:04 +04:00
if ( s > = __SIGRTMIN & & s < = __SIGRTMAX ) {
sprintf ( buf , " SIGRT_%u " , s - __SIGRTMIN ) ;
return buf ;
}
2011-08-18 14:48:56 +04:00
# endif
2014-09-10 17:46:04 +04:00
}
2011-08-18 14:48:56 +04:00
sprintf ( buf , " %d " , sig ) ;
return buf ;
1999-03-30 03:23:13 +04:00
}
1999-02-19 03:21:36 +03:00
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
static unsigned int
popcount32 ( const uint32_t * a , unsigned int size )
1999-02-19 03:21:36 +03:00
{
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
unsigned int count = 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
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
for ( ; size ; + + a , - - size ) {
uint32_t x = * a ;
1999-02-19 03:21:36 +03:00
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
# ifdef HAVE___BUILTIN_POPCOUNT
count + = __builtin_popcount ( x ) ;
2013-07-18 22:42:41 +04:00
# else
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
for ( ; x ; + + count )
x & = x - 1 ;
1999-04-06 05:19:39 +04:00
# endif
1999-02-19 03:21:36 +03:00
}
2012-01-30 01:38:35 +04:00
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
return count ;
}
static const char *
sprintsigmask_n ( const char * prefix , const void * sig_mask , unsigned int bytes )
{
/*
* The maximum number of signal names to be printed is NSIG * 2 / 3.
* Most of signal names have length 7 ,
* average length of signal names is less than 7.
* The length of prefix string does not exceed 16.
*/
static char outstr [ 128 + 8 * ( NSIG * 2 / 3 ) ] ;
char * s ;
const uint32_t * mask ;
uint32_t inverted_mask [ NSIG / 32 ] ;
unsigned int size ;
int i ;
char sep ;
s = stpcpy ( outstr , prefix ) ;
mask = sig_mask ;
/* length of signal mask in 4-byte words */
size = ( bytes > = NSIG / 8 ) ? NSIG / 32 : ( bytes + 3 ) / 4 ;
/* check whether 2/3 or more bits are set */
if ( popcount32 ( mask , size ) > = size * 32 * 2 / 3 ) {
/* show those signals that are NOT in the mask */
unsigned int j ;
for ( j = 0 ; j < size ; + + j )
inverted_mask [ j ] = ~ mask [ j ] ;
mask = inverted_mask ;
1999-02-19 03:21:36 +03:00
* s + + = ' ~ ' ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
}
2012-01-30 01:38:35 +04:00
sep = ' [ ' ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
for ( i = 0 ; ( i = next_set_bit ( mask , i , size * 32 ) ) > = 0 ; ) {
+ + i ;
* s + + = sep ;
2014-09-10 17:46:04 +04:00
if ( ( unsigned ) i < nsignals ) {
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
s = stpcpy ( s , signalent [ i ] + 3 ) ;
}
2003-09-24 02:19:32 +04:00
# ifdef SIGRTMIN
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
else if ( i > = __SIGRTMIN & & i < = __SIGRTMAX ) {
s + = sprintf ( s , " RT_%u " , i - __SIGRTMIN ) ;
}
2013-07-18 22:42:41 +04:00
# endif
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
else {
s + = sprintf ( s , " %u " , i ) ;
1999-02-19 03:21:36 +03:00
}
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +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 ;
}
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
# define tprintsigmask_addr(prefix, mask) \
tprints ( sprintsigmask_n ( ( prefix ) , ( mask ) , sizeof ( mask ) ) )
2013-07-18 22:37:06 +04:00
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
# define sprintsigmask_val(prefix, mask) \
sprintsigmask_n ( ( prefix ) , & ( mask ) , sizeof ( mask ) )
# define tprintsigmask_val(prefix, mask) \
tprints ( sprintsigmask_n ( ( prefix ) , & ( mask ) , sizeof ( mask ) ) )
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
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( struct tcb * tcp , long addr , long len )
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
{
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
char mask [ NSIG / 8 ] ;
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
2013-07-18 19:02:21 +04:00
if ( ! addr ) {
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
2013-07-18 19:02:21 +04:00
return ;
}
/* Here len is usually equals NSIG / 8 or current_wordsize.
* But we code this defensively :
*/
if ( len < 0 ) {
bad :
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
tprintf ( " %#lx " , addr ) ;
2013-07-18 19:02:21 +04:00
return ;
}
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
if ( len > = NSIG / 8 )
2013-07-18 19:02:21 +04:00
len = NSIG / 8 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
else
len = ( len + 3 ) & ~ 3 ;
if ( umoven ( tcp , addr , len , mask ) < 0 )
2013-07-18 19:02:21 +04:00
goto bad ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprints ( sprintsigmask_n ( " " , mask , len ) ) ;
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
}
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 */
2014-03-12 02:18:40 +04:00
# define SYS_SECCOMP 1 /* seccomp triggered */
2001-10-18 19:13:53 +04:00
# 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 */
2014-03-11 05:57:02 +04:00
# define SI_DETHREAD -7 /* sent by execve killing subsidiary threads */
2011-03-11 00:41:34 +03:00
# 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
2014-04-26 03:30:54 +04:00
# include "xlat/siginfo_codes.h"
# include "xlat/sigill_codes.h"
# include "xlat/sigfpe_codes.h"
# include "xlat/sigtrap_codes.h"
# include "xlat/sigchld_codes.h"
# include "xlat/sigpoll_codes.h"
# include "xlat/sigprof_codes.h"
2001-10-18 19:13:53 +04:00
# ifdef SIGEMT
2014-04-26 03:30:54 +04:00
# include "xlat/sigemt_codes.h"
2001-10-18 19:13:53 +04:00
# endif
2014-04-26 03:30:54 +04:00
# include "xlat/sigsegv_codes.h"
# include "xlat/sigbus_codes.h"
2001-10-18 19:13:53 +04:00
2014-03-12 02:18:40 +04:00
# ifndef SYS_SECCOMP
# define SYS_SECCOMP 1
# endif
2014-04-26 03:30:54 +04:00
# include "xlat/sigsys_codes.h"
2014-03-12 02:18:40 +04:00
2014-03-10 23:27:22 +04:00
static void
2014-03-11 04:05:19 +04:00
printsigsource ( const siginfo_t * sip )
{
tprintf ( " , si_pid=%lu, si_uid=%lu " ,
( unsigned long ) sip - > si_pid ,
( unsigned long ) sip - > si_uid ) ;
}
static void
printsigval ( const siginfo_t * sip , int verbose )
2014-03-10 23:27:22 +04:00
{
if ( ! verbose )
tprints ( " , ... " ) ;
else
tprintf ( " , si_value={int=%u, ptr=%#lx} " ,
sip - > si_int ,
( unsigned long ) sip - > si_ptr ) ;
}
2001-10-18 19:13:53 +04:00
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 ;
2014-03-12 02:18:40 +04:00
case SIGSYS :
code = xlookup ( sigsys_codes , sip - > si_code ) ;
break ;
2001-10-18 19:13:53 +04:00
}
}
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 ) {
2014-09-10 17:46:04 +04:00
if ( sip - > si_errno < 0 | | ( unsigned ) sip - > si_errno > = nerrnos )
2001-10-18 19:13:53 +04:00
tprintf ( " , si_errno=%d " , sip - > si_errno ) ;
else
tprintf ( " , si_errno=%s " ,
errnoent [ sip - > si_errno ] ) ;
}
# ifdef SI_FROMUSER
if ( SI_FROMUSER ( sip ) ) {
switch ( sip - > si_code ) {
2011-03-11 01:18:56 +03:00
# ifdef SI_USER
case SI_USER :
2014-03-11 04:05:19 +04:00
printsigsource ( sip ) ;
2011-03-11 01:18:56 +03:00
break ;
# endif
# ifdef SI_TKILL
case SI_TKILL :
2014-03-11 04:05:19 +04:00
printsigsource ( sip ) ;
2011-03-11 01:18:56 +03:00
break ;
# endif
2001-10-18 19:13:53 +04:00
# ifdef SI_TIMER
case SI_TIMER :
2014-03-10 23:27:22 +04:00
tprintf ( " , si_timerid=%#x, si_overrun=%d " ,
sip - > si_timerid , sip - > si_overrun ) ;
printsigval ( sip , verbose ) ;
2001-10-18 19:13:53 +04:00
break ;
2011-03-11 01:18:56 +03:00
# endif
default :
2014-03-11 04:05:19 +04:00
printsigsource ( sip ) ;
if ( sip - > si_ptr )
printsigval ( sip , verbose ) ;
2011-03-11 01:18:56 +03:00
break ;
2001-10-18 19:13:53 +04:00
}
}
else
# endif /* SI_FROMUSER */
{
switch ( sip - > si_signo ) {
case SIGCHLD :
2014-03-11 04:05:19 +04:00
printsigsource ( sip ) ;
tprints ( " , si_status= " ) ;
2001-10-18 19:13:53 +04:00
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 ;
2014-03-12 02:18:40 +04:00
# ifdef HAVE_SIGINFO_T_SI_SYSCALL
case SIGSYS :
tprintf ( " , si_call_addr=%#lx, si_syscall=%d, si_arch=%u " ,
( unsigned long ) sip - > si_call_addr ,
sip - > si_syscall , sip - > si_arch ) ;
break ;
# endif
2001-10-18 19:13:53 +04:00
default :
2011-03-11 02:14:47 +03:00
if ( sip - > si_pid | | sip - > si_uid )
2014-03-11 04:05:19 +04:00
printsigsource ( sip ) ;
if ( sip - > si_ptr )
printsigval ( sip , verbose ) ;
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
}
2013-02-13 19:31:32 +04:00
void
printsiginfo_at ( struct tcb * tcp , long addr )
{
siginfo_t si ;
if ( ! addr ) {
tprints ( " NULL " ) ;
return ;
}
if ( syserror ( tcp ) ) {
tprintf ( " %#lx " , addr ) ;
return ;
}
if ( umove ( tcp , addr , & si ) < 0 ) {
tprints ( " {???} " ) ;
return ;
}
printsiginfo ( & si , verbose ( tcp ) ) ;
}
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 ) ) {
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " " , tcp - > u_arg [ 0 ] ) ;
1999-02-19 03:21:36 +03:00
}
else if ( ! syserror ( tcp ) ) {
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tcp - > auxstr = sprintsigmask_val ( " old mask " , tcp - > u_rval ) ;
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: */
2013-12-10 07:58:42 +04:00
# ifdef MIPS
unsigned int sa_flags ;
void ( * __sa_handler ) ( int ) ;
/* Kernel treats sa_mask as an array of longs. */
unsigned long sa_mask [ NSIG / sizeof ( long ) ? NSIG / sizeof ( long ) : 1 ] ;
# else
2013-02-08 15:59:13 +04:00
void ( * __sa_handler ) ( int ) ;
1999-02-19 03:21:36 +03:00
unsigned long sa_mask ;
unsigned long sa_flags ;
2013-12-10 07:58:42 +04:00
# endif /* !MIPS */
2014-09-11 23:05:18 +04:00
# ifdef SA_RESTORER
void ( * sa_restorer ) ( void ) ;
# endif
1999-02-19 03:21:36 +03:00
} ;
2014-03-01 03:21:35 +04:00
struct old_sigaction32 {
/* sa_handler may be a libc #define, need to use other name: */
uint32_t __sa_handler ;
uint32_t sa_mask ;
uint32_t sa_flags ;
2014-09-11 23:05:18 +04:00
# ifdef SA_RESTORER
2014-03-01 03:21:35 +04:00
uint32_t sa_restorer ;
2014-09-11 23:05:18 +04:00
# endif
2014-03-01 03:21:35 +04:00
} ;
2014-01-08 02:41:30 +04:00
static void
decode_old_sigaction ( struct tcb * tcp , long addr )
1999-02-19 03:21:36 +03:00
{
struct old_sigaction sa ;
2014-03-01 03:21:35 +04:00
int r ;
1999-02-19 03:21:36 +03:00
2014-01-08 02:41:30 +04:00
if ( ! addr ) {
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
2014-01-08 02:41:30 +04:00
return ;
}
if ( ! verbose ( tcp ) | | ( exiting ( tcp ) & & syserror ( tcp ) ) ) {
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , addr ) ;
2014-01-08 02:41:30 +04:00
return ;
}
2014-03-01 03:21:35 +04:00
# if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
if ( current_wordsize ! = sizeof ( sa . __sa_handler ) & & current_wordsize = = 4 ) {
struct old_sigaction32 sa32 ;
r = umove ( tcp , addr , & sa32 ) ;
if ( r > = 0 ) {
memset ( & sa , 0 , sizeof ( sa ) ) ;
sa . __sa_handler = ( void * ) ( uintptr_t ) sa32 . __sa_handler ;
sa . sa_flags = sa32 . sa_flags ;
2014-09-11 23:05:18 +04:00
# ifdef SA_RESTORER
2014-03-01 03:21:35 +04:00
sa . sa_restorer = ( void * ) ( uintptr_t ) sa32 . sa_restorer ;
2014-09-11 23:05:18 +04:00
# endif
2014-03-01 03:21:35 +04:00
sa . sa_mask = sa32 . sa_mask ;
}
} else
# endif
{
r = umove ( tcp , addr , & sa ) ;
}
if ( r < 0 ) {
2011-09-01 12:00:28 +04:00
tprints ( " {...} " ) ;
2014-01-08 02:41:30 +04:00
return ;
}
/* Architectures using function pointers, like
* hppa , may need to manipulate the function pointer
* to compute the result of a comparison . However ,
* the __sa_handler function pointer exists only in
* the address space of the traced process , and can ' t
* be manipulated by strace . In order to prevent the
* compiler from generating code to manipulate
* __sa_handler we cast the function pointers to long . */
if ( ( long ) sa . __sa_handler = = ( long ) SIG_ERR )
tprints ( " {SIG_ERR, " ) ;
else if ( ( long ) sa . __sa_handler = = ( long ) SIG_DFL )
tprints ( " {SIG_DFL, " ) ;
else if ( ( long ) sa . __sa_handler = = ( long ) SIG_IGN )
tprints ( " {SIG_IGN, " ) ;
else
tprintf ( " {%#lx, " , ( long ) sa . __sa_handler ) ;
2013-12-10 07:58:42 +04:00
# ifdef MIPS
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_addr ( " " , sa . sa_mask ) ;
2013-12-10 07:58:42 +04:00
# else
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " " , sa . sa_mask ) ;
2013-12-10 07:58:42 +04:00
# endif
2014-01-08 02:41:30 +04:00
tprints ( " , " ) ;
printflags ( sigact_flags , sa . sa_flags , " SA_??? " ) ;
2002-12-16 02:58:41 +03:00
# ifdef SA_RESTORER
2014-01-08 02:41:30 +04:00
if ( sa . sa_flags & SA_RESTORER )
tprintf ( " , %p " , sa . sa_restorer ) ;
2002-12-16 02:58:41 +03:00
# endif
2014-01-08 02:41:30 +04:00
tprints ( " } " ) ;
}
int
sys_sigaction ( struct tcb * tcp )
{
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2014-01-08 02:41:30 +04:00
decode_old_sigaction ( tcp , tcp - > u_arg [ 1 ] ) ;
tprints ( " , " ) ;
} else
decode_old_sigaction ( tcp , tcp - > u_arg [ 2 ] ) ;
1999-02-19 03:21:36 +03:00
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 ) ) {
2013-07-17 19:26:56 +04:00
struct arm_sigcontext {
unsigned long trap_no ;
unsigned long error_code ;
unsigned long oldmask ;
unsigned long arm_r0 ;
unsigned long arm_r1 ;
unsigned long arm_r2 ;
unsigned long arm_r3 ;
unsigned long arm_r4 ;
unsigned long arm_r5 ;
unsigned long arm_r6 ;
unsigned long arm_r7 ;
unsigned long arm_r8 ;
unsigned long arm_r9 ;
unsigned long arm_r10 ;
unsigned long arm_fp ;
unsigned long arm_ip ;
unsigned long arm_sp ;
unsigned long arm_lr ;
unsigned long arm_pc ;
unsigned long arm_cpsr ;
unsigned long fault_address ;
} ;
struct arm_ucontext {
unsigned long uc_flags ;
unsigned long uc_link ; /* struct ucontext* */
/* The next three members comprise stack_t struct: */
unsigned long ss_sp ; /* void* */
unsigned long ss_flags ; /* int */
unsigned long ss_size ; /* size_t */
struct arm_sigcontext sc ;
/* These two members are sigset_t: */
unsigned long uc_sigmask [ 2 ] ;
/* more fields follow, which we aren't interested in */
} ;
struct arm_ucontext uc ;
if ( umove ( tcp , arm_regs . ARM_sp , & uc ) < 0 )
2003-06-04 03:29:04 +04:00
return 0 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
/*
* Kernel fills out uc . sc . oldmask too when it sets up signal stack ,
2013-07-17 19:26:56 +04:00
* but for sigmask restore , sigreturn syscall uses uc . uc_sigmask instead .
*/
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_addr ( " ) (mask " , uc . uc_sigmask ) ;
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 ;
2013-11-12 19:27:38 +04:00
struct sigcontext sc ;
2013-06-28 16:35:47 +04:00
if ( upeek ( tcp - > pid , 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 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_addr ( " ) (mask " , sc . oldmask ) ;
2003-06-04 03:29:04 +04:00
}
2013-07-16 14:06:25 +04:00
# elif defined(I386) || defined(X86_64)
# if defined(X86_64)
if ( current_personality = = 0 ) /* 64-bit */
return 0 ;
# endif
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
2013-07-17 19:26:56 +04:00
struct i386_sigcontext_struct {
uint16_t gs , __gsh ;
uint16_t fs , __fsh ;
uint16_t es , __esh ;
uint16_t ds , __dsh ;
uint32_t edi ;
uint32_t esi ;
uint32_t ebp ;
uint32_t esp ;
uint32_t ebx ;
uint32_t edx ;
uint32_t ecx ;
uint32_t eax ;
uint32_t trapno ;
uint32_t err ;
uint32_t eip ;
uint16_t cs , __csh ;
uint32_t eflags ;
uint32_t esp_at_signal ;
uint16_t ss , __ssh ;
uint32_t i387 ;
uint32_t oldmask ;
uint32_t cr2 ;
} ;
struct i386_fpstate {
uint32_t cw ;
uint32_t sw ;
uint32_t tag ;
uint32_t ipoff ;
uint32_t cssel ;
uint32_t dataoff ;
uint32_t datasel ;
uint8_t st [ 8 ] [ 10 ] ; /* 8*10 bytes: FP regs */
uint16_t status ;
uint16_t magic ;
uint32_t fxsr_env [ 6 ] ;
uint32_t mxcsr ;
uint32_t reserved ;
uint8_t stx [ 8 ] [ 16 ] ; /* 8*16 bytes: FP regs, each padded to 16 bytes */
uint8_t xmm [ 8 ] [ 16 ] ; /* 8 XMM regs */
uint32_t padding1 [ 44 ] ;
uint32_t padding2 [ 12 ] ; /* union with struct _fpx_sw_bytes */
} ;
2013-07-16 14:06:25 +04:00
struct {
struct i386_sigcontext_struct sc ;
struct i386_fpstate fp ;
uint32_t extramask [ 1 ] ;
} signal_stack ;
/* On i386, sc is followed on stack by struct fpstate
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
* and after it an additional u32 extramask [ 1 ] which holds
2013-07-16 14:06:25 +04:00
* upper half of the mask .
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
*/
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
uint32_t sigmask [ 2 ] ;
2013-07-16 14:06:25 +04:00
if ( umove ( tcp , * i386_esp_ptr , & signal_stack ) < 0 )
1999-02-19 03:21:36 +03:00
return 0 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
sigmask [ 0 ] = signal_stack . sc . oldmask ;
sigmask [ 1 ] = signal_stack . extramask [ 0 ] ;
tprintsigmask_addr ( " ) (mask " , sigmask ) ;
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 ;
2000-05-01 05:53:59 +04:00
/* offset of sigcontext in the kernel's sigframe structure: */
# define SIGFRAME_SC_OFFSET 0x90
2013-06-28 16:35:47 +04:00
if ( upeek ( tcp - > pid , 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 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , sc . sc_mask ) ;
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 ;
2013-11-12 19:27:38 +04:00
struct sigcontext sc ;
2013-06-26 17:53:33 +04:00
esp = ppc_regs . gpr [ 1 ] ;
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 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , sc . oldmask ) ;
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 ;
2013-06-28 16:35:47 +04:00
if ( upeek ( tcp - > pid , 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 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , sc . sc_mask ) ;
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 ;
2013-11-12 19:27:38 +04:00
struct sigcontext sc ;
2013-06-28 16:35:47 +04:00
if ( upeek ( tcp - > pid , 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 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , sc . sc_mask ) ;
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 ;
2013-02-16 11:23:40 +04:00
i1 = sparc_regs . u_regs [ U_REG_O1 ] ;
2011-06-07 14:13:24 +04:00
if ( umove ( tcp , i1 , & si ) < 0 ) {
2013-02-26 15:30:09 +04:00
perror_msg ( " sigreturn: umove " ) ;
1999-02-19 03:21:36 +03:00
return 0 ;
}
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , si . si_mask ) ;
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 ;
2013-06-28 16:35:47 +04:00
if ( upeek ( tcp - > pid , 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 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , uc . uc_sigmask ) ;
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 ;
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
2013-02-26 15:30:09 +04:00
perror_msg ( " 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 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , si . si_mask ) ;
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 ] ;
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , NULL , ( long ) regs ) < 0 ) {
2013-02-26 15:30:09 +04:00
perror_msg ( " sigreturn: PTRACE_GETREGS " ) ;
2009-02-25 20:08:40 +03:00
return 0 ;
}
if ( umove ( tcp , regs [ PT_USP ] , & sc ) < 0 )
return 0 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , sc . oldmask ) ;
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 ;
/* offset of ucontext in the kernel's sigframe structure */
2013-05-22 04:25:22 +04:00
# define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(siginfo_t)
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 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , uc . uc_sigmask ) ;
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 ;
/* Read r1, the stack pointer. */
2013-06-28 16:35:47 +04:00
if ( upeek ( tcp - > pid , 1 * 4 , & sp ) < 0 )
2010-07-06 16:21:07 +04:00
return 0 ;
if ( umove ( tcp , sp , & sc ) < 0 )
return 0 ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " ) (mask " , sc . oldmask ) ;
2010-07-06 16:21:07 +04:00
}
2013-03-25 21:22:07 +04:00
# elif defined(XTENSA)
/* Xtensa only has rt_sys_sigreturn */
2013-08-16 11:17:06 +04:00
# elif defined(ARC)
/* ARC syscall ABI only supports rt_sys_sigreturn */
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 ) ) {
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tcp - > auxstr = sprintsigmask_val ( " mask " , tcp - > u_rval ) ;
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 ) ) {
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " " , tcp - > u_arg [ 2 ] ) ;
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
2014-04-26 03:30:54 +04:00
# include "xlat/sigaltstack_flags.h"
1999-02-19 03:21:36 +03:00
2013-02-09 06:03:04 +04:00
static void
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 ;
2014-02-27 02:29:27 +04:00
int r ;
2013-02-09 06:03:04 +04:00
if ( ! addr ) {
tprints ( " NULL " ) ;
2014-02-27 02:29:27 +04:00
return ;
}
# if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
if ( current_wordsize ! = sizeof ( ss . ss_sp ) & & current_wordsize = = 4 ) {
struct {
uint32_t ss_sp ;
int32_t ss_flags ;
uint32_t ss_size ;
} ss32 ;
r = umove ( tcp , addr , & ss32 ) ;
if ( r > = 0 ) {
memset ( & ss , 0 , sizeof ( ss ) ) ;
ss . ss_sp = ( void * ) ( unsigned long ) ss32 . ss_sp ;
ss . ss_flags = ss32 . ss_flags ;
ss . ss_size = ( unsigned long ) ss32 . ss_size ;
}
} else
# endif
{
r = umove ( tcp , addr , & ss ) ;
}
if ( r < 0 ) {
2013-02-09 06:03:04 +04:00
tprintf ( " %#lx " , addr ) ;
} else {
tprintf ( " {ss_sp=%#lx, ss_flags= " , ( unsigned long ) ss . ss_sp ) ;
printflags ( sigaltstack_flags , ss . ss_flags , " SS_??? " ) ;
tprintf ( " , ss_size=%lu} " , ( unsigned long ) ss . ss_size ) ;
}
1999-02-19 03:21:36 +03:00
}
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 ) ) {
2013-02-09 06:03:04 +04:00
print_stack_t ( tcp , tcp - > u_arg [ 0 ] ) ;
1999-02-19 03:21:36 +03:00
}
else {
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2013-02-09 06:03:04 +04:00
print_stack_t ( tcp , tcp - > u_arg [ 1 ] ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
# ifdef HAVE_SIGACTION
2013-07-18 19:02:21 +04:00
/* "Old" sigprocmask, which operates with word-sized signal masks */
1999-02-19 03:21:36 +03:00
int
2011-05-30 16:00:14 +04:00
sys_sigprocmask ( struct tcb * tcp )
1999-02-19 03:21:36 +03:00
{
2013-07-18 19:02:21 +04:00
# ifdef ALPHA
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 , . . . ) ;
*/
1999-02-19 03:21:36 +03:00
printxval ( sigprocmaskcmds , tcp - > u_arg [ 0 ] , " SIG_??? " ) ;
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " , " , tcp - > u_arg [ 1 ] ) ;
1999-02-19 03:21:36 +03:00
}
else if ( ! syserror ( tcp ) ) {
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tcp - > auxstr = sprintsigmask_val ( " old mask " , tcp - > u_rval ) ;
1999-02-19 03:21:36 +03:00
return RVAL_HEX | RVAL_STR ;
}
2013-07-18 19:02:21 +04:00
# else /* !ALPHA */
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 ( " , " ) ;
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 1 ] , current_wordsize ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
}
else {
2013-07-18 19:02:21 +04:00
if ( syserror ( tcp ) )
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , tcp - > u_arg [ 2 ] ) ;
else
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 2 ] , current_wordsize ) ;
1999-02-19 03:21:36 +03:00
}
2013-07-18 19:02:21 +04:00
# endif /* !ALPHA */
1999-02-19 03:21:36 +03:00
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 ) ) {
2013-02-15 17:58:52 +04:00
tprintf ( " %ld, %s " ,
widen_to_long ( tcp - > u_arg [ 0 ] ) ,
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 " ,
2013-02-15 17:58:52 +04:00
widen_to_long ( tcp - > u_arg [ 0 ] ) ,
widen_to_long ( tcp - > u_arg [ 1 ] ) ,
signame ( tcp - > u_arg [ 2 ] )
) ;
2003-07-09 13:47:49 +04:00
}
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
{
if ( exiting ( tcp ) ) {
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 0 ] , current_wordsize ) ;
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
{
2013-07-18 19:02:21 +04:00
/* Note: arg[3] is the length of the sigset. Kernel requires NSIG / 8 */
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 ( " , " ) ;
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 1 ] , tcp - > u_arg [ 3 ] ) ;
tprints ( " , " ) ;
1999-02-19 03:21:36 +03:00
}
else {
2013-07-18 19:02:21 +04:00
if ( syserror ( tcp ) )
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , tcp - > u_arg [ 2 ] ) ;
else
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 2 ] , tcp - > u_arg [ 3 ] ) ;
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: */
2013-12-10 07:58:42 +04:00
# ifdef MIPS
unsigned int sa_flags ;
void ( * __sa_handler ) ( int ) ;
# else
2013-02-08 15:59:13 +04:00
void ( * __sa_handler ) ( int ) ;
1999-02-19 03:21:36 +03:00
unsigned long sa_flags ;
2013-12-10 07:58:42 +04:00
# endif /* !MIPS */
2014-09-11 23:05:18 +04:00
# ifdef SA_RESTORER
void ( * sa_restorer ) ( void ) ;
# endif
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 ;
2014-09-11 23:05:18 +04:00
# ifdef SA_RESTORER
2009-04-15 17:22:59 +04:00
uint32_t sa_restorer ;
2014-09-11 23:05:18 +04:00
# endif
2009-04-15 17:22:59 +04:00
uint32_t sa_mask [ 2 * ( NSIG / sizeof ( long ) ? NSIG / sizeof ( long ) : 1 ) ] ;
1999-02-19 03:21:36 +03:00
} ;
2014-01-08 02:41:30 +04:00
static void
decode_new_sigaction ( struct tcb * tcp , long addr )
1999-02-19 03:21:36 +03:00
{
struct new_sigaction sa ;
2009-04-15 17:22:59 +04:00
int r ;
1999-02-19 03:21:36 +03:00
2014-01-08 02:41:30 +04:00
if ( ! addr ) {
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
2014-01-08 02:41:30 +04:00
return ;
2009-04-15 17:22:59 +04:00
}
2014-01-08 02:41:30 +04:00
if ( ! verbose ( tcp ) | | ( exiting ( tcp ) & & syserror ( tcp ) ) ) {
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , addr ) ;
2014-01-08 02:41:30 +04:00
return ;
2009-04-15 17:22:59 +04:00
}
2013-02-13 19:31:32 +04:00
# if SUPPORTED_PERSONALITIES > 1 && 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 ;
2014-09-11 23:05:18 +04:00
# ifdef SA_RESTORER
2009-04-15 17:22:59 +04:00
sa . sa_restorer = ( void * ) ( unsigned long ) sa32 . sa_restorer ;
2014-09-11 23:05:18 +04:00
# endif
2009-04-15 17:22:59 +04:00
/* Kernel treats sa_mask as an array of longs.
* For 32 - bit process , " long " is uint32_t , thus , for example ,
* 32 th bit in sa_mask will end up as bit 0 in sa_mask [ 1 ] .
* But for ( 64 - bit ) kernel , 32 th bit in sa_mask is
* 32 th bit in 0 th ( 64 - bit ) long !
* For little - endian , it ' s the same .
* For big - endian , we swap 32 - bit words .
*/
sa . sa_mask [ 0 ] = sa32 . sa_mask [ 0 ] + ( ( long ) ( sa32 . sa_mask [ 1 ] ) < < 32 ) ;
}
} else
# endif
{
r = umove ( tcp , addr , & sa ) ;
}
if ( r < 0 ) {
2011-09-01 12:00:28 +04:00
tprints ( " {...} " ) ;
2014-01-08 02:41:30 +04:00
return ;
2009-04-15 17:22:59 +04:00
}
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 ) ;
2013-07-18 12:10:46 +04:00
/*
* Sigset size is in tcp - > u_arg [ 4 ] ( SPARC )
* or in tcp - > u_arg [ 3 ] ( all other ) ,
* but kernel won ' t handle sys_rt_sigaction
* with wrong sigset size ( just returns EINVAL instead ) .
* We just fetch the right size , which is NSIG / 8.
*/
Rewrite signal mask decoding without sigset_t
The sigset_t provided by libc is not quite convenient.
In glibc, sigset_t is an array with space for 1024 bits, which is much
more than required: all architectures supported by Linux have only 64
signals except MIPS, which has 128.
In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than
necessary.
With this change, signal mask is decoded without use of intermediate
sigset_t structure, which saves us some cpu cycles in case of glibc with
its inflated sigset_t, and enables build with libcs where sigset_t is
broken.
Old implementation used to check each signal number in the given signal
mask twice using sigismember().
New implementation is based on popcount and next_set_bit() so it's
noticeably faster.
* configure.ac: Check for __builtin_popcount.
* signal.c: Ensure that NSIG >= 32.
(sprintsigmask, sprintsigmask_long, printsigmask): Remove.
(popcount32, sprintsigmask_n): New functions.
(tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros.
(print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask,
sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use
new signal mask decoding interface.
* tests/sigaction.c (main): Add a test with almost filled signal mask.
* tests/sigaction.awk: Update.
2014-02-26 20:51:28 +04:00
tprintsigmask_val ( " " , sa . sa_mask ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2013-07-18 12:10:46 +04:00
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 ( " } " ) ;
2014-01-08 02:41:30 +04:00
}
2009-04-15 17:22:59 +04:00
2014-01-08 02:41:30 +04:00
int
sys_rt_sigaction ( struct tcb * tcp )
{
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
2011-09-01 12:00:28 +04:00
tprints ( " , " ) ;
2014-01-08 02:41:30 +04:00
decode_new_sigaction ( tcp , tcp - > u_arg [ 1 ] ) ;
tprints ( " , " ) ;
} else {
decode_new_sigaction ( tcp , tcp - > u_arg [ 2 ] ) ;
2013-02-12 14:43:46 +04:00
# if defined(SPARC) || defined(SPARC64)
1999-06-03 18:21:07 +04:00
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
2014-01-08 02:41:30 +04:00
}
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
{
if ( exiting ( tcp ) ) {
2013-07-18 19:02:21 +04:00
/*
* One of the few syscalls where sigset size ( arg [ 1 ] )
* is allowed to be < = NSIG / 8 , not strictly = = .
* This allows non - rt sigpending ( ) syscall
* to reuse rt_sigpending ( ) code in kernel .
*/
1999-02-19 03:21:36 +03:00
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] ) ;
tprintf ( " , %lu " , tcp - > u_arg [ 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 ) ) {
2013-07-18 19:02:21 +04:00
/* NB: kernel requires arg[1] == NSIG / 8 */
print_sigset_addr_len ( tcp , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] ) ;
tprintf ( " , %lu " , tcp - > u_arg [ 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 )
{
printsignal ( sig ) ;
tprints ( " , " ) ;
2013-02-13 19:31:32 +04:00
printsiginfo_at ( tcp , uinfo ) ;
2012-03-13 19:51:13 +04:00
}
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
{
2013-07-18 19:02:21 +04:00
/* NB: kernel requires arg[3] == NSIG / 8 */
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 3 ] ) ;
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 */
2013-02-13 19:31:32 +04:00
printsiginfo_at ( tcp , tcp - > u_arg [ 1 ] ) ;
tprints ( " , " ) ;
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 ] ) ;
2013-07-18 19:02:21 +04:00
tprintf ( " , %lu " , 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
{
2013-07-18 19:02:21 +04:00
/* NB: kernel requires arg[2] == NSIG / 8 */
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 ( " , " ) ;
2013-07-18 19:02:21 +04:00
print_sigset_addr_len ( tcp , tcp - > u_arg [ 1 ] , tcp - > u_arg [ 2 ] ) ;
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 ) ;
}