From: Dmitry V. Levin Date: Mon, 23 Mar 2015 00:04:27 +0000 (+0000) Subject: alpha, ia64, sh, sparc, sparc64: fix pipe and pipe2 syscalls decoding X-Git-Tag: v4.11~551 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=78ed3f3558942b7c042aeb84ee0f4a2dccf64791;p=strace alpha, ia64, sh, sparc, sparc64: fix pipe and pipe2 syscalls decoding Fix pipe syscall decoding on alpha. Fix pipe2 syscall decoding on ia64, sh, sparc, and sparc64. * configure.ac (AC_CHECK_FUNCS): Add pipe2. * defs.h [ALPHA || IA64 || SH || SPARC || SPARC64] (HAVE_GETRVAL2): Define. * net.c (do_pipe): Check HAVE_GETRVAL2 instead of architecture macros. Do not use getrval2 for pipe2 decoding. Print address if umove call fails. * syscall.c (getrval2): Check HAVE_GETRVAL2 instead of architecture macros. Implement for [ALPHA]. * tests/pipe.c: New file. * tests/pipe.expected: New file. * tests/pipe.test: New test. * tests/Makefile.am (check_PROGRAMS): Add pipe. (TESTS): Add pipe.test. (EXTRA_DIST): Add pipe.expected. * tests/.gitignore: Add pipe. --- diff --git a/configure.ac b/configure.ac index e73958ca..d829e18b 100644 --- a/configure.ac +++ b/configure.ac @@ -228,6 +228,7 @@ AC_CHECK_FUNCS(m4_normalize([ fputs_unlocked if_indextoname inet_ntop + pipe2 prctl preadv process_vm_readv diff --git a/defs.h b/defs.h index 4f6bbd96..5d2a76eb 100644 --- a/defs.h +++ b/defs.h @@ -424,8 +424,12 @@ extern int umoven(struct tcb *, long, unsigned int, void *); umoven((pid), (addr), sizeof(*(objp)), (void *) (objp)) extern int umovestr(struct tcb *, long, unsigned int, char *); extern int upeek(int pid, long, long *); -#if defined(SPARC) || defined(SPARC64) || defined(IA64) || defined(SH) + +#if defined ALPHA || defined IA64 || defined SH || defined SPARC || defined SPARC64 +# define HAVE_GETRVAL2 extern long getrval2(struct tcb *); +#else +# undef HAVE_GETRVAL2 #endif extern const char *signame(const int); diff --git a/net.c b/net.c index 276fc607..58c54c87 100644 --- a/net.c +++ b/net.c @@ -1068,18 +1068,19 @@ do_pipe(struct tcb *tcp, int flags_arg) if (syserror(tcp)) { tprintf("%#lx", tcp->u_arg[0]); } else { -#if !defined(SPARC) && !defined(SPARC64) && !defined(SH) && !defined(IA64) - int fds[2]; - - if (umoven(tcp, tcp->u_arg[0], sizeof fds, fds) < 0) - tprints("[...]"); - else - tprintf("[%u, %u]", fds[0], fds[1]); -#elif defined(SPARC) || defined(SPARC64) || defined(SH) || defined(IA64) - tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp)); -#else - tprintf("%#lx", tcp->u_arg[0]); +#ifdef HAVE_GETRVAL2 + if (flags_arg < 0) { + tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp)); + } else #endif + { + int fds[2]; + + if (umove(tcp, tcp->u_arg[0], &fds) < 0) + tprintf("%#lx", tcp->u_arg[0]); + else + tprintf("[%u, %u]", fds[0], fds[1]); + } } if (flags_arg >= 0) { tprints(", "); diff --git a/syscall.c b/syscall.c index 67af9fd8..e42b8053 100644 --- a/syscall.c +++ b/syscall.c @@ -779,7 +779,7 @@ static struct user_regs_struct arc_regs; static long get_regs_error; -#if defined(SPARC) || defined(SPARC64) || defined(IA64) || defined(SH) +#ifdef HAVE_GETRVAL2 long getrval2(struct tcb *tcp) { @@ -790,6 +790,9 @@ getrval2(struct tcb *tcp) # elif defined(SH) if (upeek(tcp->pid, 4*(REG_REG0+1), &val) < 0) return -1; +# elif defined ALPHA + if (upeek(tcp->pid, 20, &val) < 0) + return -1; # elif defined(IA64) val = ia64_regs.gr[9]; # endif diff --git a/tests/.gitignore b/tests/.gitignore index 61ff1498..38b80598 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -13,6 +13,7 @@ net-accept-connect netlink_inet_diag netlink_unix_diag pc +pipe scm_rights seccomp select diff --git a/tests/Makefile.am b/tests/Makefile.am index b8475acc..62e5d667 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -22,6 +22,7 @@ check_PROGRAMS = \ netlink_inet_diag \ netlink_unix_diag \ pc \ + pipe \ scm_rights \ seccomp \ select \ @@ -74,6 +75,7 @@ TESTS = \ net.test \ net-fd.test \ net-yy.test \ + pipe.test \ pc.test \ sun_path.test \ unix-yy.test \ @@ -105,6 +107,7 @@ EXTRA_DIST = init.sh run.sh match.awk \ net-fd.expected \ net-yy-accept.awk \ net-yy-connect.awk \ + pipe.expected \ select.awk \ sigaction.awk \ statfs.expected \ diff --git a/tests/pipe.c b/tests/pipe.c new file mode 100644 index 00000000..6a5306f3 --- /dev/null +++ b/tests/pipe.c @@ -0,0 +1,27 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +int +main(void) +{ + (void) close(0); + (void) close(1); + int fds[2]; + if (pipe(fds) || fds[0] != 0 || fds[1] != 1) + return 77; + +#ifdef HAVE_PIPE2 + (void) close(0); + (void) close(1); + if (pipe2(fds, O_NONBLOCK) || fds[0] != 0 || fds[1] != 1) + return 77; + return 0; +#else + return 77; +#endif +} diff --git a/tests/pipe.expected b/tests/pipe.expected new file mode 100644 index 00000000..675cb85b --- /dev/null +++ b/tests/pipe.expected @@ -0,0 +1,2 @@ +pipe(\(\[0, 1\]|2\(\[0, 1\], 0)\) += 0 +pipe2\(\[0, 1\], O_NONBLOCK\) += 0 diff --git a/tests/pipe.test b/tests/pipe.test new file mode 100755 index 00000000..a445f86e --- /dev/null +++ b/tests/pipe.test @@ -0,0 +1,16 @@ +#!/bin/sh + +# Check pipe/pipe2 syscalls decoding. + +. "${srcdir=.}/init.sh" + +syscall=pipe2 +for n in pipe; do + $STRACE -e$n -h > /dev/null && syscall=$syscall,$n +done + +run_prog +run_strace -e$syscall $args +match_grep + +exit 0