|
From: <sv...@va...> - 2015-02-25 14:00:26
|
Author: mjw
Date: Wed Feb 25 14:00:14 2015
New Revision: 14964
Log:
Bug #344318 socketcall should wrap recvmmsg and sendmmsg
Some architectures, e.g. s390, don't have dedicated recvmmsg and sendmmsg
system calls, but use the socketcall multiplexing system call with
SYS_RECVMMSG or SYS_SENDMMSG (just like the accept4 systemcall can also
be called through socketcall). Create separate helpers for recvmmsg and
sendmmsg helpers that can be used by either the direct syscall or the
socket call.
Modified:
trunk/NEWS
trunk/coregrind/m_syswrap/priv_syswrap-linux.h
trunk/coregrind/m_syswrap/syswrap-linux.c
trunk/include/vki/vki-linux.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Wed Feb 25 14:00:14 2015
@@ -105,6 +105,7 @@
344295 syscall recvmmsg on arm64 (243) and ppc32/64 (343) unhandled
344307 2 unhandled syscalls on aarch64/arm64: umount2(39), mount (40)
344314 callgrind_annotate ... warnings about commands containing newlines
+344318 socketcall should wrap recvmmsg and sendmmsg
344499 Fix compilation for Linux kernel >= 4. With this, also require
a Linux kernel >= 2.6 as 2.4 is mostly untested and might trigger
obvious and non-obvious issues
Modified: trunk/coregrind/m_syswrap/priv_syswrap-linux.h
==============================================================================
--- trunk/coregrind/m_syswrap/priv_syswrap-linux.h (original)
+++ trunk/coregrind/m_syswrap/priv_syswrap-linux.h Wed Feb 25 14:00:14 2015
@@ -305,6 +305,10 @@
extern void ML_(linux_PRE_sys_getsockopt) ( TId, UW, UW, UW, UW, UW );
extern void ML_(linux_POST_sys_getsockopt) ( TId, SR, UW, UW, UW, UW, UW );
extern void ML_(linux_PRE_sys_setsockopt) ( TId, UW, UW, UW, UW, UW );
+extern void ML_(linux_PRE_sys_recvmmsg) ( TId, UW, UW, UW, UW, UW );
+extern void ML_(linux_POST_sys_recvmmsg) ( TId, UW, UW, UW, UW, UW, UW );
+extern void ML_(linux_PRE_sys_sendmmsg) ( TId, UW, UW, UW, UW );
+extern void ML_(linux_POST_sys_sendmmsg) ( TId, UW, UW, UW, UW, UW );
// Linux-specific (but non-arch-specific) ptrace wrapper helpers
extern void ML_(linux_PRE_getregset) ( ThreadId, long, long );
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Wed Feb 25 14:00:14 2015
@@ -4066,6 +4066,20 @@
ML_(generic_PRE_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
break;
+ case VKI_SYS_RECVMMSG:
+ /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
+ struct timespec *timeout); */
+ PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
+ ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
+ ARG2_4 );
+ break;
+
+ case VKI_SYS_SENDMMSG:
+ /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
+ PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
+ ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
+ break;
+
default:
VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
SET_STATUS_Failure( VKI_EINVAL );
@@ -4171,6 +4185,15 @@
ML_(generic_POST_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1, RES );
break;
+ case VKI_SYS_RECVMMSG:
+ ML_(linux_POST_sys_recvmmsg)( tid, RES,
+ ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
+ break;
+
+ case VKI_SYS_SENDMMSG:
+ ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
+ break;
+
default:
VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
VG_(core_panic)("... bye!\n");
@@ -4849,64 +4872,31 @@
PRE(sys_sendmmsg)
{
- struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
- HChar name[40]; // large enough
- UInt i;
*flags |= SfMayBlock;
PRINT("sys_sendmmsg ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
PRE_REG_READ4(long, "sendmmsg",
int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
- for (i = 0; i < ARG3; i++) {
- VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
- ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
- VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
- PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
- }
+ ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
}
POST(sys_sendmmsg)
{
- if (RES > 0) {
- struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
- UInt i;
- for (i = 0; i < RES; i++) {
- POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
- }
- }
+ ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
}
PRE(sys_recvmmsg)
{
- struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
- HChar name[40]; // large enough
- UInt i;
*flags |= SfMayBlock;
PRINT("sys_recvmmsg ( %ld, %#lx, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
PRE_REG_READ5(long, "recvmmsg",
int, s, struct mmsghdr *, mmsg, int, vlen,
int, flags, struct timespec *, timeout);
- for (i = 0; i < ARG3; i++) {
- VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
- ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
- VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
- PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
- }
- if (ARG5)
- PRE_MEM_READ( "recvmmsg(timeout)", ARG5, sizeof(struct vki_timespec) );
+ ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
}
POST(sys_recvmmsg)
{
- if (RES > 0) {
- struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
- HChar name[32]; // large enough
- UInt i;
- for (i = 0; i < RES; i++) {
- VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
- ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
- POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
- }
- }
+ ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
}
/* ---------------------------------------------------------------------
@@ -10274,6 +10264,69 @@
}
}
+void
+ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
+ UWord arg1, UWord arg2, UWord arg3,
+ UWord arg4, UWord arg5 )
+{
+ struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
+ HChar name[40]; // large enough
+ UInt i;
+ for (i = 0; i < arg3; i++) {
+ VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
+ ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
+ VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
+ PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
+ }
+ if (arg5)
+ PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
+}
+
+void
+ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
+ UWord arg1, UWord arg2, UWord arg3,
+ UWord arg4, UWord arg5 )
+{
+ if (res > 0) {
+ struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
+ HChar name[32]; // large enough
+ UInt i;
+ for (i = 0; i < res; i++) {
+ VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
+ ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
+ POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
+ }
+ }
+}
+
+void
+ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
+ UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
+{
+ struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
+ HChar name[40]; // large enough
+ UInt i;
+ for (i = 0; i < arg3; i++) {
+ VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
+ ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
+ VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
+ PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
+ }
+}
+
+void
+ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
+ UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
+{
+ if (res > 0) {
+ struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
+ UInt i;
+ for (i = 0; i < res; i++) {
+ POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
+ }
+ }
+}
+
/* ---------------------------------------------------------------------
ptrace wrapper helpers
------------------------------------------------------------------ */
Modified: trunk/include/vki/vki-linux.h
==============================================================================
--- trunk/include/vki/vki-linux.h (original)
+++ trunk/include/vki/vki-linux.h Wed Feb 25 14:00:14 2015
@@ -596,6 +596,8 @@
#define VKI_SYS_SENDMSG 16 /* sys_sendmsg(2) */
#define VKI_SYS_RECVMSG 17 /* sys_recvmsg(2) */
#define VKI_SYS_ACCEPT4 18 /* sys_accept4(2) */
+#define VKI_SYS_RECVMMSG 19 /* sys_recvmmsg(2) */
+#define VKI_SYS_SENDMMSG 20 /* sys_sendmmsg(2) */
#ifndef ARCH_HAS_SOCKET_TYPES
enum vki_sock_type {
|