]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add support for preadv and pwritev. Fixes #212149.
authorTom Hughes <tom@compton.nu>
Wed, 28 Oct 2009 10:04:11 +0000 (10:04 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 28 Oct 2009 10:04:11 +0000 (10:04 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10914

coregrind/m_syswrap/priv_syswrap-linux.h
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-ppc64-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c

index a0e4ab04c388e38d3c9b618fc0f2609b6ad8e6ee..cc3e98c6cbaafbf32ebbd24e826807404e4ec631 100644 (file)
@@ -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);
index 5675570d9f3ccadcdbc02a40e89fdfb85fb8147e..293dc2560de081462a4da3edb4daf1333ff06a16 100644 (file)
@@ -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
 };
index 6eb8a27cd14e64026fed161394c64d55ca8de602..26c6bed3dd3829407470ebd89b240c5464f63625 100644 (file)
@@ -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
    ------------------------------------------------------------------ */
index 5e949f1cf1fc016e526e2c6945b2f9cfa90dd3b7..f275768f9c5b732223e6ddd638606fe83bf81d99 100644 (file)
@@ -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
 };
 
index 21e0a2443e164bb49e74f2e736ba684d3db51d97..75fd0a9b22e5658a2d8961ae793ecd6a6e8b9ec9 100644 (file)
@@ -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
 };
 
index 2264fd0abdaecb72c3e139c7eb2f1155739f3541..74401e00bc47b7a72ba0e45650fd736cc33158b1 100644 (file)
@@ -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