diff options
-rw-r--r-- | tapset/aux_syscalls.stp | 44 | ||||
-rw-r--r-- | tapset/syscalls2.stp | 2 | ||||
-rwxr-xr-x | testsuite/systemtap.syscall/test.tcl | 11 |
3 files changed, 55 insertions, 2 deletions
diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index 6e45e8e1..4577d64e 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -1851,6 +1851,8 @@ function _struct_sigaction32_u:string(uaddr:long) #include <linux/compat.h> // There seems to be no public cross arch header that defines this. + // For x86, you can find it in asm/ia32.h. For s390x, it is defined + // in a private header. struct sigaction32 { compat_uptr_t sa_handler; unsigned int sa_flags; @@ -1869,9 +1871,11 @@ function _struct_sigaction32_u:string(uaddr:long) sizeof(struct sigaction32)) == 0) { struct sigaction act; + act.sa_handler = (void *)compat_ptr(act32.sa_handler); act.sa_flags = (unsigned long)act32.sa_flags; act.sa_restorer = (void *)compat_ptr(act32.sa_restorer); + /* swap words around to get right endian order. */ switch (_NSIG_WORDS) { @@ -1884,6 +1888,46 @@ function _struct_sigaction32_u:string(uaddr:long) case 1: act.sa_mask.sig[0] = act32.sa_mask.sig[0] | (((long)act32.sa_mask.sig[1]) << 32); } + + _stp_sigaction_str(&act, THIS->__retvalue, MAXSTRINGLEN); + } + else + strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN); + } +#endif +%} + +function _struct_old_sigaction32_u:string(uaddr:long) +%{ /* pure */ +#ifdef CONFIG_COMPAT +#include <linux/compat.h> + + // There seems to be no public cross arch header that defines this. + // For x86, you can find it in asm/ia32.h. For s390x, it is defined + // in a private header. + struct old_sigaction32 { + compat_uptr_t sa_handler; + compat_old_sigset_t sa_mask; /* A 32 bit mask */ + unsigned int sa_flags; + unsigned int sa_restorer; /* Another 32 bit pointer */ + }; + + struct old_sigaction32 act32; + char *ptr = (char *)(unsigned long)THIS->uaddr; + + if (ptr == NULL) + strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN); + else + { + if(_stp_copy_from_user((char*)&act32, ptr, + sizeof(struct old_sigaction32)) == 0) + { + struct sigaction act; + + act.sa_handler = (void *)compat_ptr(act32.sa_handler); + act.sa_restorer = (void *)compat_ptr(act32.sa_restorer); + act.sa_flags = (unsigned long)act32.sa_flags; + siginitset(&act.sa_mask, act32.sa_mask); _stp_sigaction_str(&act, THIS->__retvalue, MAXSTRINGLEN); } else diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp index 37f07afb..8f4e1b8a 100644 --- a/tapset/syscalls2.stp +++ b/tapset/syscalls2.stp @@ -2463,7 +2463,7 @@ probe syscall.sigaction32 = kernel.function("sys32_sigaction").call ? sig = $sig act_uaddr = $act oact_uaddr = $oact - argstr = sprintf("%s, %p, %p", _signal_name($sig), $act, $oact) + argstr = sprintf("%s, {%s}, %p", _signal_name($sig), _struct_old_sigaction32_u($act), $oact) } probe syscall.sigaction32.return = kernel.function("sys32_sigaction").return ? { diff --git a/testsuite/systemtap.syscall/test.tcl b/testsuite/systemtap.syscall/test.tcl index e640db66..9d620d74 100755 --- a/testsuite/systemtap.syscall/test.tcl +++ b/testsuite/systemtap.syscall/test.tcl @@ -46,10 +46,19 @@ proc run_one_test {filename flags bits} { set sys_prog "[file dirname [file normalize $filename]]/sys.stp" set cmd "stap --skip-badvars -c $dir/${testname} ${sys_prog}" + # Extract additional C flags needed to compile + set add_flags "" + foreach i $flags { + if [regexp "^additional_flags=" $i] { + regsub "^additional_flags=" $i "" tmp + append add_flags " $tmp" + } + } + # Extract the expected results # Use the preprocessor so we can ifdef tests in and out - set ccmd "gcc -E -C -P $filename" + set ccmd "gcc -E -C -P $add_flags $filename" # XXX: but note, this will expand all system headers too! catch {eval exec $ccmd} output |