static void dumpio(struct tcb *tcp) { if (syserror(tcp)) return; int fd = tcp->u_arg[0]; if (fd < 0) return; if (is_number_in_set(fd, read_set)) { switch (tcp->s_ent->sen) { case SEN_read: case SEN_pread: case SEN_recv: case SEN_recvfrom: case SEN_mq_timedreceive: dumpstr(tcp, tcp->u_arg[1], tcp->u_rval); return; case SEN_readv: case SEN_preadv: case SEN_preadv2: dumpiov_upto(tcp, tcp->u_arg[2], tcp->u_arg[1], tcp->u_rval); return; case SEN_recvmsg: dumpiov_in_msghdr(tcp, tcp->u_arg[1], tcp->u_rval); return; case SEN_recvmmsg: dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]); return; } } if (is_number_in_set(fd, write_set)) { switch (tcp->s_ent->sen) { case SEN_write: case SEN_pwrite: case SEN_send: case SEN_sendto: case SEN_mq_timedsend: dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); break; case SEN_writev: case SEN_pwritev: case SEN_pwritev2: case SEN_vmsplice: dumpiov_upto(tcp, tcp->u_arg[2], tcp->u_arg[1], -1); break; case SEN_sendmsg: dumpiov_in_msghdr(tcp, tcp->u_arg[1], -1); break; case SEN_sendmmsg: dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]); break; } } }
void dumpiov_in_msghdr(struct tcb *tcp, long addr, unsigned long data_size) { struct msghdr msg; if (extractmsghdr(tcp, addr, &msg)) dumpiov_upto(tcp, msg.msg_iovlen, (long)msg.msg_iov, data_size); }
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_upto(tcp, mmsg.msg_hdr.msg_iovlen, (long)mmsg.msg_hdr.msg_iov, mmsg.msg_len); } } }