]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Added support for epoll_pwait(), utimensat(), eventfd(), timerfd() and signalfd(...
authorBart Van Assche <bvanassche@acm.org>
Sat, 26 Apr 2008 07:45:10 +0000 (07:45 +0000)
committerBart Van Assche <bvanassche@acm.org>
Sat, 26 Apr 2008 07:45:10 +0000 (07:45 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7917

12 files changed:
configure.in
coregrind/m_syswrap/priv_syswrap-linux.h
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-generic.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
memcheck/tests/Makefile.am
memcheck/tests/linux-syscalls-2007.c [new file with mode: 0644]
memcheck/tests/linux-syscalls-2007.stderr.exp [new file with mode: 0644]
memcheck/tests/linux-syscalls-2007.vgtest [new file with mode: 0644]

index c3fd234d5e1cac6712747b7a8399ac281a3c03c9..97d298029308c1dc392a3dd096ddaf7a0eb16544 100644 (file)
@@ -953,7 +953,15 @@ fi
 
 # Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS([sys/endian.h endian.h mqueue.h])
+AC_CHECK_HEADERS([       \
+        endian.h         \
+        mqueue.h         \
+        sys/endian.h     \
+        sys/epoll.h      \
+        sys/eventfd.h    \
+        sys/poll.h       \
+        sys/signalfd.h   \
+        ])
 
 
 # Checks for typedefs, structures, and compiler characteristics.
@@ -968,8 +976,27 @@ AC_FUNC_MEMCMP
 AC_FUNC_MMAP
 AC_TYPE_SIGNAL
 
-AC_CHECK_FUNCS([floor memchr memset mkdir strchr strdup strpbrk strrchr strstr semtimedop])
-AC_CHECK_FUNCS([mallinfo])
+AC_CHECK_FUNCS([     \
+        epoll_create \
+        epoll_pwait  \
+        eventfd      \
+        eventfd_read \
+        floor        \
+        mallinfo     \
+        memchr       \
+        memset       \
+        mkdir        \
+        ppoll        \
+        semtimedop   \
+        signalfd     \
+        strchr       \
+        strdup       \
+        strpbrk      \
+        strrchr      \
+        strstr       \
+        timerfd      \
+        utimensat    \
+        ])
 
 
 # Do we have a useable MPI setup on the primary and/or secondary targets?
index 115c4363ae041ea18107b10d3d4204b83217a485..0033494fbfb8eec02378a11eba4144a4c646f3af 100644 (file)
@@ -82,6 +82,8 @@ DECL_TEMPLATE(linux, sys_ppoll);
 DECL_TEMPLATE(linux, sys_epoll_create);
 DECL_TEMPLATE(linux, sys_epoll_ctl);
 DECL_TEMPLATE(linux, sys_epoll_wait);
+DECL_TEMPLATE(linux, sys_epoll_pwait);
+DECL_TEMPLATE(linux, sys_eventfd);
 
 DECL_TEMPLATE(linux, sys_gettid);
 DECL_TEMPLATE(linux, sys_set_tid_address);
@@ -124,6 +126,9 @@ DECL_TEMPLATE(linux, sys_timer_settime);
 DECL_TEMPLATE(linux, sys_timer_gettime);
 DECL_TEMPLATE(linux, sys_timer_getoverrun);
 DECL_TEMPLATE(linux, sys_timer_delete);
+DECL_TEMPLATE(linux, sys_timerfd);
+
+DECL_TEMPLATE(linux, sys_signalfd);
 
 DECL_TEMPLATE(linux, sys_capget);
 DECL_TEMPLATE(linux, sys_capset);
index b49c27d60f0ea17480d0a17472c4428c5e499784..24c1a539d1e28470305ec0c46f5c91846a7dec6c 100644 (file)
@@ -1370,7 +1370,7 @@ const SyscallTableEntry ML_(syscall_table)[] = {
    LINX_(__NR_faccessat,        sys_faccessat),        // 269
 
    LINX_(__NR_pselect6,                 sys_pselect6),         // 270
-//   LINXY(__NR_ppoll,          sys_ni_syscall),       // 271
+   LINXY(__NR_ppoll,            sys_ppoll),            // 271
 //   LINX_(__NR_unshare,                sys_unshare),          // 272
    LINX_(__NR_set_robust_list,  sys_set_robust_list),  // 273
    LINXY(__NR_get_robust_list,  sys_get_robust_list),  // 274
@@ -1380,6 +1380,12 @@ const SyscallTableEntry ML_(syscall_table)[] = {
    LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
 //   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 278
 //   LINX_(__NR_move_pages,        sys_ni_syscall),       // 279
+   LINX_(__NR_utimensat,         sys_utimensat),        // 280
+   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 281
+   LINXY(__NR_signalfd,          sys_signalfd),         // 282
+   LINXY(__NR_timerfd,           sys_timerfd),          // 283
+   LINX_(__NR_eventfd,           sys_eventfd),          // 284
+//   LINX_(__NR_fallocate,        sys_ni_syscall),        // 285
 };
 
 const UInt ML_(syscall_table_size) = 
index 4820713da9316fded804c5e64629579e12e1a3ba..d7e0755ca20363a665ad75f431a5c49c07330974 100644 (file)
@@ -5638,7 +5638,7 @@ PRE(sys_utimes)
    PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
    PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
    if (ARG2 != 0)
-      PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
+      PRE_MEM_READ( "utimes(tvp)", ARG2, 2 * sizeof(struct vki_timeval) );
 }
 
 PRE(sys_acct)
index 0f4b8f33afa368649b19f01f368a876d3f482d1c..a0cabc324f89e6cf0a28a843d49abe77f8c2fa22 100644 (file)
@@ -988,7 +988,7 @@ PRE(sys_ppoll)
    UInt i;
    struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
    *flags |= SfMayBlock;
-   PRINT("sys_ppoll ( %p, %d, %p, %p, %llu )\n", ARG1,ARG2,ARG3,ARG4,ARG5);
+   PRINT("sys_ppoll ( %p, %d, %p, %p, %llu )\n", ARG1,ARG2,ARG3,ARG4,(ULong)ARG5);
    PRE_REG_READ5(long, "ppoll",
                  struct vki_pollfd *, ufds, unsigned int, nfds,
                  struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
@@ -1072,6 +1072,41 @@ POST(sys_epoll_wait)
       POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
 }
 
+PRE(sys_epoll_pwait)
+{
+   *flags |= SfMayBlock;
+   PRINT("sys_epoll_pwait ( %d, %p, %d, %d, %p, %llu )", ARG1,ARG2,ARG3,ARG4,ARG5,(ULong)ARG6);
+   PRE_REG_READ6(long, "epoll_pwait",
+                 int, epfd, struct vki_epoll_event *, events,
+                 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
+                 vki_size_t, sigsetsize);
+   PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
+   if (ARG4)
+      PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
+}
+POST(sys_epoll_pwait)
+{
+   vg_assert(SUCCESS);
+   if (RES > 0)
+      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
+}
+
+PRE(sys_eventfd)
+{
+   PRINT("sys_eventfd ( %u )", ARG1);
+   PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
+}
+POST(sys_eventfd)
+{
+   if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
+      VG_(close)(RES);
+      SET_STATUS_Failure( VKI_EMFILE );
+   } else {
+      if (VG_(clo_track_fds))
+         ML_(record_fd_open_nameless) (tid, RES);
+   }
+}
+
 /* ---------------------------------------------------------------------
    tid-related wrappers
    ------------------------------------------------------------------ */
@@ -1672,6 +1707,27 @@ PRE(sys_timer_delete)
    PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
 }
 
+PRE(sys_timerfd)
+{
+   PRINT("sys_timerfd ( %d, %d, %p )", ARG1, ARG2, ARG3);
+   PRE_REG_READ3(long, "sys_timerfd",
+                 int, fd, int, clockid, const struct itimerspec *, tmr);
+   PRE_MEM_READ( "timerfd(tmr)", ARG3,
+                  sizeof(struct vki_itimerspec) );
+   if (ARG1 != -1 && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
+      SET_STATUS_Failure( VKI_EBADF );
+}
+POST(sys_timerfd)
+{
+   if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
+      VG_(close)(RES);
+      SET_STATUS_Failure( VKI_EMFILE );
+   } else {
+      if (VG_(clo_track_fds))
+         ML_(record_fd_open_nameless) (tid, RES);
+   }
+}
+
 /* ---------------------------------------------------------------------
    capabilities wrappers
    ------------------------------------------------------------------ */
@@ -2220,6 +2276,27 @@ POST(sys_sigprocmask)
 }
 #endif
 
+PRE(sys_signalfd)
+{
+   PRINT("sys_signalfd ( %d, %p, %llu )", ARG1, ARG2, (ULong) ARG3);
+   PRE_REG_READ3(long, "sys_signalfd",
+                 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
+   PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
+   if (ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
+      SET_STATUS_Failure( VKI_EBADF );
+}
+POST(sys_signalfd)
+{
+   if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
+      VG_(close)(RES);
+      SET_STATUS_Failure( VKI_EMFILE );
+   } else {
+      if (VG_(clo_track_fds))
+         ML_(record_fd_open_nameless) (tid, RES);
+   }
+}
+
+
 /* ---------------------------------------------------------------------
    rt_sig* wrappers
    ------------------------------------------------------------------ */
@@ -2542,7 +2619,17 @@ PRE(sys_futimesat)
                  int, dfd, char *, filename, struct timeval *, tvp);
    PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
    if (ARG3 != 0)
-      PRE_MEM_READ( "futimesat(tvp)", ARG3, sizeof(struct vki_timeval) );
+      PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
+}
+
+PRE(sys_utimensat)
+{
+   PRINT("sys_utimensat ( %d, %p(%s), %p, 0x%x )", ARG1,ARG2,ARG2,ARG3,ARG4);
+   PRE_REG_READ4(long, "utimensat",
+                 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
+   PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
+   if (ARG3 != 0)
+      PRE_MEM_READ( "utimensat(tvp)", ARG3, 2 * sizeof(struct vki_timespec) );
 }
 
 PRE(sys_newfstatat)
@@ -2823,19 +2910,6 @@ PRE(sys_ioprio_set)
    PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
 }
 
-
-/* XXX I don't think this is really the right place for this.
-   Move it elsewhere in this file? */
-PRE(sys_utimensat)
-{
-   PRINT("sys_utimensat ( %d, %p(%s), %p )", ARG1,ARG2,ARG2,ARG3);
-   PRE_REG_READ3(long, "utimensat",
-                 int, dfd, char *, filename, struct timespec *, tvp);
-   PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
-   if (ARG3 != 0)
-      PRE_MEM_READ( "utimensat(tvp)", ARG3, sizeof(struct vki_timespec) );
-}
-
 #undef PRE
 #undef POST
 
index 2da51116c1cfd804c58ebd0338cffade425d777c..92e4d40356e29b1be79f583877f9dc6b1d5795e8 100644 (file)
@@ -1823,6 +1823,15 @@ const SyscallTableEntry ML_(syscall_table)[] = {
    LINX_(__NR_faccessat,         sys_faccessat),         // 298
    LINX_(__NR_set_robust_list,   sys_set_robust_list),   // 299
    LINXY(__NR_get_robust_list,   sys_get_robust_list),   // 300
+//   LINX_(__NR_move_pages,        sys_ni_syscall),        // 301
+//   LINX_(__NR_getcpu,            sys_ni_syscall),        // 302
+   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),       // 303
+   LINX_(__NR_utimensat,         sys_utimensat),         // 304
+   LINXY(__NR_signalfd,          sys_signalfd),          // 305
+   LINXY(__NR_timerfd,           sys_timerfd),           // 306
+   LINX_(__NR_eventfd,           sys_eventfd),           // 307
+//   LINX_(__NR_sync_file_range2,   sys_ni_syscall),       // 308
+//   LINX_(__NR_fallocate,        sys_ni_syscall),         // 309
 };
 
 const UInt ML_(syscall_table_size) = 
index ebf975fba0636a2a6f26080d43df2dc59c61cf5c..28934e48c656f455715eef0e91d73e8daad4b3cb 100644 (file)
@@ -1478,7 +1478,15 @@ const SyscallTableEntry ML_(syscall_table)[] = {
    LINX_(__NR_faccessat,         sys_faccessat),          // 298
    LINX_(__NR_set_robust_list,   sys_set_robust_list),    // 299
    LINXY(__NR_get_robust_list,   sys_get_robust_list),    // 300
-
+//   LINX_(__NR_move_pages,        sys_ni_syscall),        // 301
+//   LINX_(__NR_getcpu,            sys_ni_syscall),        // 302
+   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),       // 303
+   LINX_(__NR_utimensat,         sys_utimensat),         // 304
+   LINXY(__NR_signalfd,          sys_signalfd),          // 305
+   LINXY(__NR_timerfd,           sys_timerfd),           // 306
+   LINX_(__NR_eventfd,           sys_eventfd),           // 307
+//   LINX_(__NR_sync_file_range2,   sys_ni_syscall),       // 308
+//   LINX_(__NR_fallocate,        sys_ni_syscall),         // 309
 };
 
 const UInt ML_(syscall_table_size) = 
index 80193101ff0076f2ec3cc1e404b6e889ac465ab5..b96007cc287a9c87819a809d1f92b7c7ffc8a260 100644 (file)
@@ -2224,9 +2224,13 @@ const SyscallTableEntry ML_(syscall_table)[] = {
 //   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 316
 //   LINX_(__NR_move_pages,        sys_ni_syscall),       // 317
 //   LINX_(__NR_getcpu,            sys_ni_syscall),       // 318
-//   LINX_(__NR_epoll_pwait,       sys_ni_syscall),       // 319
+   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 319
 
    LINX_(__NR_utimensat,         sys_utimensat),        // 320
+   LINXY(__NR_signalfd,          sys_signalfd),         // 321
+   LINXY(__NR_timerfd,           sys_timerfd),          // 322
+   LINX_(__NR_eventfd,           sys_eventfd),          // 323
+//   LINX_(__NR_fallocate,        sys_ni_syscall),        // 324
 };
 
 const UInt ML_(syscall_table_size) = 
index 8bc298b05145debfef2e46b86fca2682098723fe..e75c2d38f6218df4ba0ff95c8d52cd8a0748d38f 100644 (file)
@@ -65,6 +65,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        leak-tree.stderr.exp2 leak-tree.stderr.exp64 \
        leak-regroot.vgtest leak-regroot.stderr.exp \
        leakotron.vgtest leakotron.stdout.exp leakotron.stderr.exp \
+       linux-syscalls-2007 linux-syscalls-2007.stderr.exp \
        long_namespace_xml.vgtest long_namespace_xml.stdout.exp \
        long_namespace_xml.stderr.exp \
        lsframe1.vgtest lsframe1.stdout.exp lsframe1.stderr.exp \
@@ -170,6 +171,7 @@ check_PROGRAMS = \
        doublefree error_counts errs1 exitprog execve execve2 erringfds \
        fprw fwrite hello inits inline \
        leak-0 leak-cycle leak-pool leak-tree leak-regroot leakotron \
+       linux-syscalls-2007 \
        long_namespace_xml \
        lsframe1 lsframe2 \
        mallinfo \
diff --git a/memcheck/tests/linux-syscalls-2007.c b/memcheck/tests/linux-syscalls-2007.c
new file mode 100644 (file)
index 0000000..0cbafa1
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * Test program for some Linux syscalls introduced during 2006 and 2007:
+ * - epoll_pwait() was introduced in the 2.6.19 kernel, released in November
+ *     2006.
+ * - utimensat(), eventfd(), timerfd() and signalfd() were introduced in the
+ *     2.6.22 kernel, released in July 2007.
+ *
+ * See also http://bugs.kde.org/show_bug.cgi?id=160907.
+ */
+
+#define _GNU_SOURCE
+
+#include "../../config.h"
+#include <fcntl.h>
+#include <signal.h>
+#if defined(HAVE_SYS_EPOLL_H)
+#include <sys/epoll.h>
+#endif
+#if defined(HAVE_SYS_EVENTFD_H)
+#include <sys/eventfd.h>
+#endif
+#if defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+#if defined(HAVE_SYS_SIGNALFD_H)
+#include <sys/signalfd.h>
+#endif
+#include <sys/stat.h>
+#include <unistd.h>
+
+int main (void)
+{
+#if defined(HAVE_SIGNALFD) && defined(HAVE_EVENTFD) \
+    && defined(HAVE_EVENTFD_READ) && defined(HAVE_PPOLL)
+  {
+    sigset_t mask;
+    sigemptyset (&mask);
+    sigaddset (&mask, SIGUSR1);
+    int fd = signalfd (-1, &mask, 0);
+    sigaddset (&mask, SIGUSR2);
+    fd = signalfd (fd, &mask, 0);
+    int fd2 = eventfd (5, 0);
+    eventfd_t ev;
+    eventfd_read (fd2, &ev);
+    struct timespec ts = { .tv_sec = 1, .tv_nsec = 0 };
+    struct pollfd pfd[2] = { [0].fd = fd, [0].events = POLLIN|POLLOUT,
+                             [1].fd = fd2, [1].events = POLLIN|POLLOUT };
+    ppoll (pfd, 2, &ts, &mask);
+  }
+#endif
+
+#if defined(HAVE_UTIMENSAT)
+  unlink("/tmp/valgrind-utimensat-test");
+  close (creat ("/tmp/valgrind-utimensat-test", S_IRUSR | S_IWUSR));
+  {
+    struct timespec ts2[2] = { [0].tv_sec = 10000000, [1].tv_sec = 20000000 };
+    utimensat (AT_FDCWD, "/tmp/valgrind-utimensat-test", ts2, 0);
+  }
+  unlink("/tmp/valgrind-utimensat-test");
+#endif
+
+#if defined(HAVE_EPOLL_CREATE) && defined(HAVE_EPOLL_PWAIT)
+  {
+    int fd3 = epoll_create (10);
+    struct epoll_event evs[10];
+    sigset_t mask;
+    sigemptyset (&mask);
+    sigaddset (&mask, SIGUSR1);
+    sigaddset (&mask, SIGUSR2);
+    epoll_pwait (fd3, evs, 10, 0, &mask);
+  }
+#endif
+
+  return 0;
+}
diff --git a/memcheck/tests/linux-syscalls-2007.stderr.exp b/memcheck/tests/linux-syscalls-2007.stderr.exp
new file mode 100644 (file)
index 0000000..c4aa6f0
--- /dev/null
@@ -0,0 +1,7 @@
+
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
+malloc/free: in use at exit: 0 bytes in 0 blocks.
+malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
+For a detailed leak analysis,  rerun with: --leak-check=yes
+For counts of detected errors, rerun with: -v
diff --git a/memcheck/tests/linux-syscalls-2007.vgtest b/memcheck/tests/linux-syscalls-2007.vgtest
new file mode 100644 (file)
index 0000000..55e548a
--- /dev/null
@@ -0,0 +1 @@
+prog: linux-syscalls-2007