diff --git a/Makefile.am b/Makefile.am index ecdafbf7..adddc615 100644 --- a/Makefile.am +++ b/Makefile.am @@ -66,6 +66,7 @@ libstrace_a_CFLAGS = $(strace_CFLAGS) libstrace_a_SOURCES = \ fstatfs.c \ fstatfs64.c \ + socketcall.c \ statfs.c \ statfs64.c \ sync_file_range.c \ diff --git a/linux/dummy.h b/linux/dummy.h index bb23f5dd..cfc2c3e3 100644 --- a/linux/dummy.h +++ b/linux/dummy.h @@ -113,7 +113,6 @@ #define sys_setsid printargs #define sys_set_tid_address printargs #define sys_setup printargs -#define sys_socketcall printargs #define sys_sync printargs #define sys_syscall printargs #define sys_vhangup printargs diff --git a/socketcall.c b/socketcall.c new file mode 100644 index 00000000..3f188213 --- /dev/null +++ b/socketcall.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "defs.h" +#include "xlat/socketcalls.h" + +SYS_FUNC(socketcall) +{ + const unsigned int call = tcp->u_arg[0]; + const char *str = xlookup(socketcalls, call); + + if (str) + tprints(str); + else + tprintf("%d", call); + + unsigned int i; + for (i = 1; i < MAX_ARGS; ++i) + tprintf(", %#lx", tcp->u_arg[i]); + + return RVAL_DECODED; +} diff --git a/syscall.c b/syscall.c index 5c83818c..7a842ccc 100644 --- a/syscall.c +++ b/syscall.c @@ -567,29 +567,26 @@ qualify(const char *s) static void decode_socket_subcall(struct tcb *tcp) { - unsigned long addr; - unsigned int n; + const int call = tcp->u_arg[0]; - if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_socket_nsubcalls) + if (call < 1 || call >= SYS_socket_nsubcalls) return; - tcp->scno = SYS_socket_subcall + tcp->u_arg[0]; - tcp->qual_flg = qual_flags[tcp->scno]; - tcp->s_ent = &sysent[tcp->scno]; - addr = tcp->u_arg[1]; - n = tcp->s_ent->nargs; - if (sizeof(tcp->u_arg[0]) == current_wordsize) { - memset(tcp->u_arg, 0, n * sizeof(tcp->u_arg[0])); - (void) umoven(tcp, addr, n * sizeof(tcp->u_arg[0]), tcp->u_arg); - } else { - unsigned int args[n]; - unsigned int i; + const unsigned long scno = SYS_socket_subcall + call; + const unsigned int nargs = sysent[scno].nargs; + uint64_t buf[nargs]; - memset(args, 0, sizeof(args)); - (void) umove(tcp, addr, &args); - for (i = 0; i < n; ++i) - tcp->u_arg[i] = args[i]; - } + if (umoven(tcp, tcp->u_arg[1], nargs * current_wordsize, buf) < 0) + return; + + tcp->scno = scno; + tcp->qual_flg = qual_flags[scno]; + tcp->s_ent = &sysent[scno]; + + unsigned int i; + for (i = 0; i < nargs; ++i) + tcp->u_arg[i] = (sizeof(uint32_t) == current_wordsize) + ? ((uint32_t *) buf)[i] : buf[i]; } #endif diff --git a/xlat/socketcalls.in b/xlat/socketcalls.in new file mode 100644 index 00000000..3ffeb6f2 --- /dev/null +++ b/xlat/socketcalls.in @@ -0,0 +1,20 @@ +SYS_SOCKET 1 +SYS_BIND 2 +SYS_CONNECT 3 +SYS_LISTEN 4 +SYS_ACCEPT 5 +SYS_GETSOCKNAME 6 +SYS_GETPEERNAME 7 +SYS_SOCKETPAIR 8 +SYS_SEND 9 +SYS_RECV 10 +SYS_SENDTO 11 +SYS_RECVFROM 12 +SYS_SHUTDOWN 13 +SYS_SETSOCKOPT 14 +SYS_GETSOCKOPT 15 +SYS_SENDMSG 16 +SYS_RECVMSG 17 +SYS_ACCEPT4 18 +SYS_RECVMMSG 19 +SYS_SENDMMSG 20