aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2015-03-23 00:04:27 +0000
committerDmitry V. Levin <ldv@altlinux.org>2015-03-23 03:16:51 +0000
commit78ed3f3558942b7c042aeb84ee0f4a2dccf64791 (patch)
tree02ca48d39fdc42d3c03e6a6df245ce7af79e177c
parentc215569efe58a0045c921219635da02ee8e5451b (diff)
downloadandroid_external_strace-78ed3f3558942b7c042aeb84ee0f4a2dccf64791.tar.gz
android_external_strace-78ed3f3558942b7c042aeb84ee0f4a2dccf64791.tar.bz2
android_external_strace-78ed3f3558942b7c042aeb84ee0f4a2dccf64791.zip
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.
-rw-r--r--configure.ac1
-rw-r--r--defs.h6
-rw-r--r--net.c23
-rw-r--r--syscall.c5
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/pipe.c27
-rw-r--r--tests/pipe.expected2
-rwxr-xr-xtests/pipe.test16
9 files changed, 71 insertions, 13 deletions
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 <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
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