From: Tom Hughes Date: Wed, 28 Oct 2009 10:04:11 +0000 (+0000) Subject: Add support for preadv and pwritev. Fixes #212149. X-Git-Tag: svn/VALGRIND_3_6_0~495 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33d5189e1ac3094379fda239a3780b2caa8b634a;p=thirdparty%2Fvalgrind.git Add support for preadv and pwritev. Fixes #212149. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10914 --- diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index a0e4ab04c3..cc3e98c6cb 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -48,6 +48,8 @@ DECL_TEMPLATE(linux, sys_mount); DECL_TEMPLATE(linux, sys_oldumount); DECL_TEMPLATE(linux, sys_umount); DECL_TEMPLATE(linux, sys_perf_counter_open); +DECL_TEMPLATE(linux, sys_preadv); +DECL_TEMPLATE(linux, sys_pwritev); // POSIX, but various sub-cases differ between Linux and Darwin. DECL_TEMPLATE(linux, sys_fcntl); diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 5675570d9f..293dc2560d 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -1377,8 +1377,8 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINXY(__NR_pipe2, sys_pipe2), // 293 LINXY(__NR_inotify_init1, sys_inotify_init1), // 294 - // (__NR_preadv, sys_ni_syscall) // 295 - // (__NR_pwritev, sys_ni_syscall) // 296 + LINXY(__NR_preadv, sys_preadv), // 295 + LINX_(__NR_pwritev, sys_pwritev), // 296 // (__NR_rt_tgsigqueueinfo, sys_ni_syscall) // 297 LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 298 }; diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 6eb8a27cd1..26c6bed3dd 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -3004,6 +3004,97 @@ PRE(sys_faccessat) PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 ); } +/* --------------------------------------------------------------------- + p{read,write}v wrappers + ------------------------------------------------------------------ */ + +PRE(sys_preadv) +{ + Int i; + struct vki_iovec * vec; + *flags |= SfMayBlock; +#if VG_WORDSIZE == 4 + PRINT("sys_preadv ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,LOHI64(ARG4,ARG5)); + PRE_REG_READ5(ssize_t, "preadv", + unsigned long, fd, const struct iovec *, vector, + unsigned long, count, vki_u32, offset_low32, + vki_u32, offset_high32); +#elif VG_WORDSIZE == 8 + PRINT("sys_preadv ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,(Long)ARG4); + PRE_REG_READ4(ssize_t, "preadv", + unsigned long, fd, const struct iovec *, vector, + unsigned long, count, Word, offset); +#else +# error Unexpected word size +#endif + if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) { + SET_STATUS_Failure( VKI_EBADF ); + } else { + PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) ); + + if (ARG2 != 0) { + /* ToDo: don't do any of the following if the vector is invalid */ + vec = (struct vki_iovec *)ARG2; + for (i = 0; i < (Int)ARG3; i++) + PRE_MEM_WRITE( "preadv(vector[...])", + (Addr)vec[i].iov_base, vec[i].iov_len ); + } + } +} + +POST(sys_preadv) +{ + vg_assert(SUCCESS); + if (RES > 0) { + Int i; + struct vki_iovec * vec = (struct vki_iovec *)ARG2; + Int remains = RES; + + /* RES holds the number of bytes read. */ + for (i = 0; i < (Int)ARG3; i++) { + Int nReadThisBuf = vec[i].iov_len; + if (nReadThisBuf > remains) nReadThisBuf = remains; + POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf ); + remains -= nReadThisBuf; + if (remains < 0) VG_(core_panic)("preadv: remains < 0"); + } + } +} + +PRE(sys_pwritev) +{ + Int i; + struct vki_iovec * vec; + *flags |= SfMayBlock; +#if VG_WORDSIZE == 4 + PRINT("sys_pwritev ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,LOHI64(ARG4,ARG5)); + PRE_REG_READ5(ssize_t, "pwritev", + unsigned long, fd, const struct iovec *, vector, + unsigned long, count, vki_u32, offset_low32, + vki_u32, offset_high32); +#elif VG_WORDSIZE == 8 + PRINT("sys_pwritev ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,(Long)ARG4); + PRE_REG_READ4(ssize_t, "pwritev", + unsigned long, fd, const struct iovec *, vector, + unsigned long, count, Word, offset); +#else +# error Unexpected word size +#endif + if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) { + SET_STATUS_Failure( VKI_EBADF ); + } else { + PRE_MEM_READ( "pwritev(vector)", + ARG2, ARG3 * sizeof(struct vki_iovec) ); + if (ARG2 != 0) { + /* ToDo: don't do any of the following if the vector is invalid */ + vec = (struct vki_iovec *)ARG2; + for (i = 0; i < (Int)ARG3; i++) + PRE_MEM_READ( "pwritev(vector[...])", + (Addr)vec[i].iov_base, vec[i].iov_len ); + } + } +} + /* --------------------------------------------------------------------- key retention service wrappers ------------------------------------------------------------------ */ diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index 5e949f1cf1..f275768f9c 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -1869,8 +1869,8 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINXY(__NR_pipe2, sys_pipe2), // 317 LINXY(__NR_inotify_init1, sys_inotify_init1), // 318 LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 319 - // (__NR_preadv, sys_ni_syscall) // 320 - // (__NR_pwritev, sys_ni_syscall) // 321 + LINXY(__NR_preadv, sys_preadv), // 320 + LINX_(__NR_pwritev, sys_pwritev), // 321 // (__NR_rt_tgsigqueueinfo, sys_ni_syscall) // 322 }; diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index 21e0a2443e..75fd0a9b22 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -1509,8 +1509,8 @@ const SyscallTableEntry ML_(syscall_table)[] = { LINXY(__NR_pipe2, sys_pipe2), // 317 LINXY(__NR_inotify_init1, sys_inotify_init1), // 318 LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 319 - // (__NR_preadv, sys_ni_syscall) // 320 - // (__NR_pwritev, sys_ni_syscall) // 321 + LINXY(__NR_preadv, sys_preadv), // 320 + LINX_(__NR_pwritev, sys_pwritev), // 321 // (__NR_rt_tgsigqueueinfo, sys_ni_syscall) // 322 }; diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 2264fd0abd..74401e00bc 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -2255,8 +2255,8 @@ const SyscallTableEntry ML_(syscall_table)[] = { // (__NR_dup3, sys_ni_syscall) // 330 LINXY(__NR_pipe2, sys_pipe2), // 331 LINXY(__NR_inotify_init1, sys_inotify_init1), // 332 - // (__NR_preadv, sys_ni_syscall) // 333 - // (__NR_pwritev, sys_ni_syscall) // 334 + LINXY(__NR_preadv, sys_preadv), // 333 + LINX_(__NR_pwritev, sys_pwritev), // 334 // (__NR_rt_tgsigqueueinfo, sys_ni_syscall) // 335 LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 336