From: Mike Frysinger Date: Thu, 15 Mar 2012 04:45:33 +0000 (-0400) Subject: alpha: fix decode of osf_sigprocmask X-Git-Tag: v4.7~88 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dde045c13f77ca477aa59e19d0b50ae4afa906b6;p=strace 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 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 --- diff --git a/linux/alpha/syscallent.h b/linux/alpha/syscallent.h index c7297cd0..85c341a4 100644 --- a/linux/alpha/syscallent.h +++ b/linux/alpha/syscallent.h @@ -76,7 +76,7 @@ { 3, TD|TF, sys_open, "open" }, /* 45 */ { 5, 0, printargs, "osf_old_sigaction" }, /* 46, not implemented */ { 1, NF, sys_getgid, "getxgid" }, /* 47 */ - { 3, TS, printargs, "osf_sigprocmask" }, /* 48 */ + { 2, TS, sys_sigprocmask, "osf_sigprocmask" }, /* 48 */ { 5, 0, printargs, "osf_getlogin" }, /* 49, not implemented */ { 5, 0, printargs, "osf_setlogin" }, /* 50, not implemented */ { 1, TF, sys_acct, "acct" }, /* 51 */ diff --git a/signal.c b/signal.c index bffdec04..5ff89e43 100644 --- a/signal.c +++ b/signal.c @@ -1180,13 +1180,27 @@ int sys_sigprocmask(struct tcb *tcp) { #ifdef ALPHA + sigset_t ss; if (entering(tcp)) { + /* + * 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, ...); + */ + memcpy(&ss, &tcp->u_arg[1], sizeof(long)); printxval(sigprocmaskcmds, tcp->u_arg[0], "SIG_???"); tprints(", "); - printsigmask(tcp->u_arg[1], 0); + printsigmask(&ss, 0); } else if (!syserror(tcp)) { - tcp->auxstr = sprintsigmask("old mask ", tcp->u_rval, 0); + memcpy(&ss, &tcp->u_rval, sizeof(long)); + tcp->auxstr = sprintsigmask("old mask ", &ss, 0); return RVAL_HEX | RVAL_STR; } #else /* !ALPHA */