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.
This commit is contained in:
Дмитрий Левин 2015-03-23 00:04:27 +00:00
parent c215569efe
commit 78ed3f3558
9 changed files with 71 additions and 13 deletions

View File

@ -228,6 +228,7 @@ AC_CHECK_FUNCS(m4_normalize([
fputs_unlocked
if_indextoname
inet_ntop
pipe2
prctl
preadv
process_vm_readv

6
defs.h
View File

@ -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);

23
net.c
View File

@ -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(", ");

View File

@ -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

1
tests/.gitignore vendored
View File

@ -13,6 +13,7 @@ net-accept-connect
netlink_inet_diag
netlink_unix_diag
pc
pipe
scm_rights
seccomp
select

View 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 \

27
tests/pipe.c Normal file
View File

@ -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
}

2
tests/pipe.expected Normal file
View File

@ -0,0 +1,2 @@
pipe(\(\[0, 1\]|2\(\[0, 1\], 0)\) += 0
pipe2\(\[0, 1\], O_NONBLOCK\) += 0

16
tests/pipe.test Executable file
View File

@ -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