]> granicus.if.org Git - strace/commitdiff
alpha, ia64, sh, sparc, sparc64: fix pipe and pipe2 syscalls decoding
authorDmitry V. Levin <ldv@altlinux.org>
Mon, 23 Mar 2015 00:04:27 +0000 (00:04 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 23 Mar 2015 03:16:51 +0000 (03:16 +0000)
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.

configure.ac
defs.h
net.c
syscall.c
tests/.gitignore
tests/Makefile.am
tests/pipe.c [new file with mode: 0644]
tests/pipe.expected [new file with mode: 0644]
tests/pipe.test [new file with mode: 0755]

index e73958caabb6a257015c0769f9e58771a30d32c1..d829e18b45211acece1e1d98743ad5fbf2e73a4f 100644 (file)
@@ -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 4f6bbd960320c782e860f1d21efa427dc2d14dcc..5d2a76eb229d002effa25d38dbae1388f10b979c 100644 (file)
--- 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 276fc60798030b6123c995287dae7dd466b06298..58c54c875b867a5ea50a060e5b3dbdf5a1847a44 100644 (file)
--- 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(", ");
index 67af9fd811e0d5207f1aa501fa966cffef8d0fc4..e42b8053a3140a1005a45fd603e16fed8051a77b 100644 (file)
--- 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
index 61ff1498af7b9ae5e9cee394b0de9fd56c7a3a11..38b805988d14d35a41300e0fc14f047720a83bd1 100644 (file)
@@ -13,6 +13,7 @@ net-accept-connect
 netlink_inet_diag
 netlink_unix_diag
 pc
+pipe
 scm_rights
 seccomp
 select
index b8475accd15e1bed9fbee5e198071f1d95c4bcd8..62e5d667c91ba31b94347f5e31031e465ba6e9aa 100644 (file)
@@ -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 (file)
index 0000000..6a5306f
--- /dev/null
@@ -0,0 +1,27 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+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 (file)
index 0000000..675cb85
--- /dev/null
@@ -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 (executable)
index 0000000..a445f86
--- /dev/null
@@ -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