summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tapset/aux_syscalls.stp44
-rw-r--r--tapset/syscalls2.stp2
-rwxr-xr-xtestsuite/systemtap.syscall/test.tcl11
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