From: David Smith Date: Thu, 2 Jan 2014 17:58:40 +0000 (-0600) Subject: PR16207 partial fix: Fix the 'rt_signal' [nd_]syscall.exp tests on rawhide. X-Git-Tag: release-2.5~373 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=afefbbb3b11573690f4cf04791e984e2b1f67d55;p=systemtap.git PR16207 partial fix: Fix the 'rt_signal' [nd_]syscall.exp tests on rawhide. * tapset/linux/syscalls2.stp: Fix syscall nesting in 'syscall.rt_sigprocmask' and 'syscall.compat_rt_sigprocmask' probes. * tapset/linux/nd_syscalls.stp: Ditto. * tapset/linux/aux_syscalls.stp: Added __uint32() function. * runtime/linux/compat_unistd.h: Added '__NR_compat_rt_sigprocmask' define. --- diff --git a/runtime/linux/compat_unistd.h b/runtime/linux/compat_unistd.h index c8ce4d70f..79d85100e 100644 --- a/runtime/linux/compat_unistd.h +++ b/runtime/linux/compat_unistd.h @@ -39,6 +39,9 @@ #ifndef __NR_ia32_readlinkat #define __NR_ia32_readlinkat 305 #endif +#ifndef __NR_ia32_rt_sigprocmask +#define __NR_ia32_rt_sigprocmask 175 +#endif #ifndef __NR_ia32_symlinkat #define __NR_ia32_symlinkat 304 #endif @@ -54,6 +57,7 @@ #define __NR_compat_linkat __NR_ia32_linkat #define __NR_compat_pipe2 __NR_ia32_pipe2 #define __NR_compat_readlinkat __NR_ia32_readlinkat +#define __NR_compat_rt_sigprocmask __NR_ia32_rt_sigprocmask #define __NR_compat_symlinkat __NR_ia32_symlinkat #define __NR_compat_umount2 __NR_ia32_umount2 @@ -72,6 +76,7 @@ #define __NR_compat_linkat __NR_linkat #define __NR_compat_pipe2 __NR_pipe2 #define __NR_compat_readlinkat __NR_readlinkat +#define __NR_compat_rt_sigprocmask __NR_rt_sigprocmask #define __NR_compat_symlinkat __NR_symlinkat #define __NR_compat_umount2 __NR_umount2 diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index 82f0e5293..1433cb30a 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -1640,6 +1640,10 @@ function __int32:long(val:long) %{ /* pure */ STAP_RETVALUE = (int32_t)STAP_ARG_val; %} +function __uint32:long(val:long) %{ /* pure */ + STAP_RETVALUE = (uint32_t)STAP_ARG_val; +%} + /* Unsigned values can get get sign-extended and become negative. */ function __ulong:long(val:long) %{ /* pure */ STAP_RETVALUE = (unsigned long)STAP_ARG_val; diff --git a/tapset/linux/nd_syscalls2.stp b/tapset/linux/nd_syscalls2.stp index 788e9a58f..d256dd12e 100644 --- a/tapset/linux/nd_syscalls2.stp +++ b/tapset/linux/nd_syscalls2.stp @@ -1460,6 +1460,11 @@ probe nd_syscall.rt_sigpending.return = kprobe.function("sys_rt_sigpending").ret # probe nd_syscall.rt_sigprocmask = kprobe.function("sys_rt_sigprocmask") ? { +%( arch != "x86_64" || kernel_v < "3.4" || CONFIG_COMPAT != "y" %? + // In kernels < 3.4, a 32-bit rt_sigprocmask call goes through + // sys32_rt_sigprocmask(). + @__syscall_gate(%{ __NR_rt_sigprocmask %}) +%) name = "rt_sigprocmask" // how = $how // how_str = _sigprocmask_how_str($how) @@ -1471,13 +1476,41 @@ probe nd_syscall.rt_sigprocmask = kprobe.function("sys_rt_sigprocmask") ? how = int_arg(1) how_str = _sigprocmask_how_str(how) set_uaddr = pointer_arg(2) - oldset_uaddr = pointer_arg(3) - argstr = sprintf("%s, [%s], %p, %d", how_str, - _stp_sigset_u(set_uaddr), oldset_uaddr, uint_arg(4)) + + // In kernels 3.4+, the following kernel commit changed the + // way rt_sigprocmask is handled on x86: + // + // commit 2c73ce734653f96542a070f3c3b3e3d1cd0fba02 + // Author: H. Peter Anvin + // Date: Sun Feb 19 09:48:01 2012 -0800 + // + // x86-64, ia32: Drop sys32_rt_sigprocmask + // + // On those kernels, a call to the 32-bit rt_sigprocmask goes + // straight to the 64-bit rt_sigprocmask function. +%( arch == "x86_64" && kernel_v >= "3.4" && CONFIG_COMPAT == "y" %? + if (%{ _stp_is_compat_task() %} + && _stp_syscall_nr() == %{ __NR_compat_rt_sigprocmask %}) { + oldset_uaddr = uint_arg(3) + argstr = sprintf("%s, [%s], %p, %d", how_str, + _stp_compat_sigset_u(set_uaddr), oldset_uaddr, + int_arg(4)) + } + else +%) + { + oldset_uaddr = pointer_arg(3) + argstr = sprintf("%s, [%s], %p, %d", how_str, + _stp_sigset_u(set_uaddr), oldset_uaddr, + uint_arg(4)) + } } probe nd_syscall.rt_sigprocmask.return = kprobe.function("sys_rt_sigprocmask").return ? { +%( arch != "x86_64" || kernel_v < "3.4" || CONFIG_COMPAT != "y" %? + @__syscall_gate(%{ __NR_rt_sigprocmask %}) +%) name = "rt_sigprocmask" retstr = returnstr(1) } diff --git a/tapset/linux/syscalls2.stp b/tapset/linux/syscalls2.stp index fe66edb66..5543c39cf 100644 --- a/tapset/linux/syscalls2.stp +++ b/tapset/linux/syscalls2.stp @@ -1302,17 +1302,49 @@ probe syscall.rt_sigpending.return = kernel.function("sys_rt_sigpending").return # probe syscall.rt_sigprocmask = kernel.function("sys_rt_sigprocmask").call ? { +%( arch != "x86_64" || kernel_v < "3.4" || CONFIG_COMPAT != "y" %? + // In kernels < 3.4, a 32-bit rt_sigprocmask call goes through + // sys32_rt_sigprocmask(). + @__syscall_gate(%{ __NR_rt_sigprocmask %}) +%) name = "rt_sigprocmask" how = $how how_str = _sigprocmask_how_str($how) set_uaddr = @choose_defined($set, $nset) - oldset_uaddr = $oset - argstr = sprintf("%s, [%s], %p, %d", how_str, _stp_sigset_u(set_uaddr), - $oset, $sigsetsize) + + // In kernels 3.4+, the following kernel commit changed the + // way rt_sigprocmask is handled on x86: + // + // commit 2c73ce734653f96542a070f3c3b3e3d1cd0fba02 + // Author: H. Peter Anvin + // Date: Sun Feb 19 09:48:01 2012 -0800 + // + // x86-64, ia32: Drop sys32_rt_sigprocmask + // + // On those kernels, a call to the 32-bit rt_sigprocmask goes + // straight to the 64-bit rt_sigprocmask function. +%( arch == "x86_64" && kernel_v >= "3.4" && CONFIG_COMPAT == "y" %? + if (%{ _stp_is_compat_task() %} + && _stp_syscall_nr() == %{ __NR_compat_rt_sigprocmask %}) { + oldset_uaddr = __uint32($oset) + argstr = sprintf("%s, [%s], %p, %d", how_str, + _stp_compat_sigset_u(set_uaddr), oldset_uaddr, + __int32($sigsetsize)) + } + else +%) + { + oldset_uaddr = $oset + argstr = sprintf("%s, [%s], %p, %d", how_str, + _stp_sigset_u(set_uaddr), $oset, $sigsetsize) + } } probe syscall.rt_sigprocmask.return = kernel.function("sys_rt_sigprocmask").return ? { +%( arch != "x86_64" || kernel_v < "3.4" || CONFIG_COMPAT != "y" %? + @__syscall_gate(%{ __NR_rt_sigprocmask %}) +%) name = "rt_sigprocmask" retstr = return_str(1, $return) }