From c74bc9e5e177f947cdac9788d0272fa4d66780b9 Mon Sep 17 00:00:00 2001 From: David Smith Date: Wed, 13 Jan 2010 09:30:12 -0600 Subject: Fix PR11160 by handling ppc syscall.sigaction32 correctly. * tapset/aux_syscalls.stp (_struct_old_sigaction32_u): New function. * tapset/syscalls2.stp (syscall.sigaction32): Uses new _struct_old_sigaction32() function to provide a human readable version of the sigaction argument. * testsuite/systemtap.syscall/test.tcl (run_one_test): Use additional C flags when pre-processing test files to better determine which tests are valid on which platforms. --- tapset/aux_syscalls.stp | 44 ++++++++++++++++++++++++++++++++++++++++++++ tapset/syscalls2.stp | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) (limited to 'tapset') 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 // 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 + + // 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 ? { -- cgit