Decode recvmmsg syscall
* net.c (do_msghr): New function to print struct msghdr.
(printmsghdr): Use it.
(printmmsghdr, sys_recvmmsg): New.
* linux/syscall.h: Declare sys_recvmmsg.
(SYS_sub_recvmmsg): Define.
(SYS_socket_nsubcalls): Bump.
* linux/sparc/syscall.h: Likewise.
* linux/arm/syscallent.h: Add sys_recvmmsg.
* linux/bfin/syscallent.h: Likewise.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/ia64/syscallent.h: Adjust.
diff --git a/net.c b/net.c
index 511f720..ded21a3 100644
--- a/net.c
+++ b/net.c
@@ -1185,6 +1185,30 @@
}
static void
+do_msghdr(struct tcb *tcp, struct msghdr *msg)
+{
+ tprintf("{msg_name(%d)=", msg->msg_namelen);
+ printsock(tcp, (long)msg->msg_name, msg->msg_namelen);
+
+ tprintf(", msg_iov(%lu)=", (unsigned long)msg->msg_iovlen);
+ tprint_iov(tcp, (unsigned long)msg->msg_iovlen,
+ (unsigned long)msg->msg_iov);
+
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ tprintf(", msg_controllen=%lu", (unsigned long)msg->msg_controllen);
+ if (msg->msg_controllen)
+ printcmsghdr(tcp, (unsigned long) msg->msg_control,
+ msg->msg_controllen);
+ tprintf(", msg_flags=");
+ printflags(msg_flags, msg->msg_flags, "MSG_???");
+#else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
+ tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
+ (unsigned long) msg->msg_accrights, msg->msg_accrightslen);
+#endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
+ tprintf("}");
+}
+
+static void
printmsghdr(tcp, addr)
struct tcb *tcp;
long addr;
@@ -1195,27 +1219,28 @@
tprintf("%#lx", addr);
return;
}
- tprintf("{msg_name(%d)=", msg.msg_namelen);
- printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
-
- tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
- tprint_iov(tcp, (unsigned long)msg.msg_iovlen,
- (unsigned long)msg.msg_iov);
-
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
- if (msg.msg_controllen)
- printcmsghdr(tcp, (unsigned long) msg.msg_control,
- msg.msg_controllen);
- tprintf(", msg_flags=");
- printflags(msg_flags, msg.msg_flags, "MSG_???");
-#else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
- tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
- (unsigned long) msg.msg_accrights, msg.msg_accrightslen);
-#endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
- tprintf("}");
+ do_msghdr(tcp, &msg);
}
+#ifdef LINUX
+static void
+printmmsghdr(struct tcb *tcp, long addr)
+{
+ struct mmsghdr {
+ struct msghdr msg_hdr;
+ unsigned msg_len;
+ } mmsg;
+
+ if (umove(tcp, addr, &mmsg) < 0) {
+ tprintf("%#lx", addr);
+ return;
+ }
+ tprintf("{");
+ do_msghdr(tcp, &mmsg.msg_hdr);
+ tprintf(", %u}", mmsg.msg_len);
+}
+#endif
+
#endif /* HAVE_SENDMSG */
/*
@@ -1503,6 +1528,24 @@
return 0;
}
+#ifdef LINUX
+int
+sys_recvmmsg(struct tcb *tcp)
+{
+ if (entering(tcp)) {
+ tprintf("%ld, ", tcp->u_arg[0]);
+ printmmsghdr(tcp, tcp->u_arg[1]);
+ tprintf(", %ld, ", tcp->u_arg[2]);
+ /* flags */
+ printflags(msg_flags, tcp->u_arg[3], "MSG_???");
+ /* timeout */
+ tprintf(", ");
+ print_timespec(tcp, tcp->u_arg[4]);
+ }
+ return 0;
+}
+#endif
+
#endif /* HAVE_SENDMSG */
int