Add functions for dumping iovecs in mmsghdr used in sendmmsg and recvmmsg

This patch is similar to what I did in commit
02f9f6b386.
That commit was for sendmsg and recvmsg system calls.
This one is for sendmmsg and recvmmsg system calls.

* defs.h (dumpiov_in_mmsghdr): New declaration.
* net.c (extractmmsghdr): New function derived from printmmsghdr.
(printmmsghdr): Use it.
(dumpiov_in_mmsghdr): New function.
* syscall.c (dumpio) [HAVE_SENDMSG]: Call dumpiov_in_mmsghdr
for recvmmsg and sendmmsg syscalls.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
This commit is contained in:
Masatake YAMATO 2014-11-07 01:23:26 +09:00 committed by Dmitry V. Levin
parent caf6a438f9
commit a807dceca5
3 changed files with 50 additions and 28 deletions

1
defs.h
View File

@ -673,6 +673,7 @@ extern void addflags(const struct xlat *, int);
extern int printflags(const struct xlat *, int, const char *);
extern const char *sprintflags(const char *, const struct xlat *, int);
extern void dumpiov_in_msghdr(struct tcb *, long);
extern void dumpiov_in_mmsghdr(struct tcb *, long);
extern void dumpiov(struct tcb *, int, long);
extern void dumpstr(struct tcb *, long, int);
extern void printstr(struct tcb *, long, long);

73
net.c
View File

@ -467,6 +467,29 @@ extractmsghdr(struct tcb *tcp, long addr, struct msghdr *msg)
return true;
}
static bool
extractmmsghdr(struct tcb *tcp, long addr, unsigned int idx, struct mmsghdr *mmsg)
{
#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
if (current_wordsize == 4) {
struct mmsghdr32 mmsg32;
addr += sizeof(struct mmsghdr32) * idx;
if (umove(tcp, addr, &mmsg32) < 0)
return false;
copy_from_msghdr32(&mmsg->msg_hdr, &mmsg32.msg_hdr);
mmsg->msg_len = mmsg32.msg_len;
} else
#endif
{
addr += sizeof(*mmsg) * idx;
if (umove(tcp, addr, mmsg) < 0)
return false;
}
return true;
}
static void
printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
{
@ -492,35 +515,13 @@ printmmsghdr(struct tcb *tcp, long addr, unsigned int idx, unsigned long msg_len
{
struct mmsghdr mmsg;
#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
if (current_wordsize == 4) {
struct mmsghdr32 mmsg32;
addr += sizeof(mmsg32) * idx;
if (umove(tcp, addr, &mmsg32) < 0) {
tprintf("%#lx", addr);
return;
}
mmsg.msg_hdr.msg_name = (void*)(long)mmsg32.msg_hdr.msg_name;
mmsg.msg_hdr.msg_namelen = mmsg32.msg_hdr.msg_namelen;
mmsg.msg_hdr.msg_iov = (void*)(long)mmsg32.msg_hdr.msg_iov;
mmsg.msg_hdr.msg_iovlen = mmsg32.msg_hdr.msg_iovlen;
mmsg.msg_hdr.msg_control = (void*)(long)mmsg32.msg_hdr.msg_control;
mmsg.msg_hdr.msg_controllen = mmsg32.msg_hdr.msg_controllen;
mmsg.msg_hdr.msg_flags = mmsg32.msg_hdr.msg_flags;
mmsg.msg_len = mmsg32.msg_len;
} else
#endif
{
addr += sizeof(mmsg) * idx;
if (umove(tcp, addr, &mmsg) < 0) {
tprintf("%#lx", addr);
return;
}
if (extractmmsghdr(tcp, addr, idx, &mmsg)) {
tprints("{");
do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
tprintf(", %u}", mmsg.msg_len);
}
tprints("{");
do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
tprintf(", %u}", mmsg.msg_len);
else
tprintf("%#lx", addr);
}
static void
@ -547,6 +548,22 @@ decode_mmsg(struct tcb *tcp, unsigned long msg_len)
printflags(msg_flags, tcp->u_arg[3], "MSG_???");
}
void
dumpiov_in_mmsghdr(struct tcb *tcp, long addr)
{
unsigned int len = tcp->u_rval;
unsigned int i;
struct mmsghdr mmsg;
for (i = 0; i < len; ++i) {
if (extractmmsghdr(tcp, addr, i, &mmsg)) {
tprintf(" = %lu buffers in vector %u\n",
(unsigned long)mmsg.msg_hdr.msg_iovlen, i);
dumpiov(tcp, mmsg.msg_hdr.msg_iovlen,
(long)mmsg.msg_hdr.msg_iov);
}
}
}
#endif /* HAVE_SENDMSG */
/*

View File

@ -2500,6 +2500,8 @@ dumpio(struct tcb *tcp)
#if HAVE_SENDMSG
else if (func == sys_recvmsg)
dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
else if (func == sys_recvmmsg)
dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
#endif
return;
}
@ -2514,6 +2516,8 @@ dumpio(struct tcb *tcp)
#if HAVE_SENDMSG
else if (func == sys_sendmsg)
dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
else if (func == sys_sendmmsg)
dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
#endif
return;
}