]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD: Add syscall wrapper for kqueuex (FreeBSD 15)
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 17 Sep 2023 09:06:05 +0000 (11:06 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 17 Sep 2023 09:08:41 +0000 (11:08 +0200)
17 files changed:
.gitignore
NEWS
coregrind/m_syswrap/priv_syswrap-freebsd.h
coregrind/m_syswrap/syswrap-freebsd.c
memcheck/tests/freebsd/Makefile.am
memcheck/tests/freebsd/kqueue.c [new file with mode: 0644]
memcheck/tests/freebsd/kqueue.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/kqueue.stdout.exp [new file with mode: 0644]
memcheck/tests/freebsd/kqueue.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/kqueuex.c [new file with mode: 0644]
memcheck/tests/freebsd/kqueuex.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/kqueuex.stdout.exp [new file with mode: 0644]
memcheck/tests/freebsd/kqueuex.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/scalar_15_plus.c
memcheck/tests/freebsd/scalar_15_plus.stderr.exp
memcheck/tests/freebsd/toucher1 [new file with mode: 0755]
memcheck/tests/freebsd/toucher2 [new file with mode: 0755]

index 76fd2f261b3e36a5df99305301901198abd84446..44533e66fa8d285a0e6e6bbc7c77ea5fb8c3c5d5 100644 (file)
 /memcheck/tests/freebsd/getfsstat
 /memcheck/tests/freebsd/inlinfo
 /memcheck/tests/freebsd/inlinfo_nested.so
+/memcheck/tests/freebsd/kqueue
+/memcheck/tests/freebsd/kqueuex
 /memcheck/tests/freebsd/linkat
 /memcheck/tests/freebsd/memalign
 /memcheck/tests/freebsd/misc
diff --git a/NEWS b/NEWS
index b4a9dfd1e437c5f4c2a8dba7c818c2b445622612..736e33baf59e847d78de2d5d2827dc41590de2de 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,7 +21,9 @@ AMD64/macOS 10.13 and nanoMIPS/Linux.
 * ================== PLATFORM CHANGES =================
 
 * Support has been added for FreeBSD 14 and FreeBSD 15.
-* Add support for the FreeBSD close_range system call.
+* Add support for the folllowing FreeBSD system calls:
+  close_range, kqueuex, timerfd_create, timerfd_settime and
+  timerfd_gettime (all added in FreeBSD 15).
 
 * ==================== TOOL CHANGES ===================
 
index 79e52b9fdfe50ac2a1a6ccd04c096f40a1593889..b02d9fb4a5b40dadbc5964e0facbfcb2453335a3 100644 (file)
@@ -562,7 +562,7 @@ DECL_TEMPLATE(freebsd, sys_swapoff) // 582
 #endif
 
 #if (FREEBSD_VERS >= FREEBSD_15)
-// unimpl __NR_kqueuex             583
+DECL_TEMPLATE(freebsd, sys_kqueuex); // 583
 // unimpl __NR_membarrier          584
 DECL_TEMPLATE(freebsd, sys_timerfd_create); // 585
 DECL_TEMPLATE(freebsd, sys_timerfd_gettime); // 586
index ffe12ef7991799e8cdf21787eb4fb09a0acadaa7..fda60920c2a31460be9ecd1b1046e46f3cbe2683 100644 (file)
@@ -3455,8 +3455,8 @@ POST(sys_getresgid)
 // int kqueue(void);
 PRE(sys_kqueue)
 {
-   PRINT("%s", "sys_kqueue ()");
-   PRE_REG_READ0(omt, "kqueue");
+   PRINT("%s", "sys_kqueue(void)");
+   PRE_REG_READ0(int, "kqueue");
 }
 
 POST(sys_kqueue)
@@ -6769,7 +6769,7 @@ PRE(sys___specialfd)
 // int swapoff(const char *special, u_int flags);
 PRE(sys_swapoff)
 {
-   PRINT("sys_swapoff ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,(char *)ARG1, ARG2);
+   PRINT("sys_swapoff(%#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u)", ARG1,(char *)ARG1, ARG2);
    PRE_REG_READ2(int, "swapoff", const char *, special, u_int, flags);
    PRE_MEM_RASCIIZ( "swapoff(special)", ARG1 );
 }
@@ -6778,7 +6778,25 @@ PRE(sys_swapoff)
 
 #if (FREEBSD_VERS >= FREEBSD_15)
 
-// SYS_kqueuex 583 unimpl
+// SYS_kqueuex 583
+// int kqueuex(u_int flags);
+PRE(sys_kqueuex)
+{
+   PRINT("sys_kqueuex(%#" FMT_REGWORD "x)", ARG1);
+   PRE_REG_READ1(int, "kqueuex", u_int, flags);
+}
+
+POST(sys_kqueuex)
+{
+   if (!ML_(fd_allowed)(RES, "kqueuex", tid, True)) {
+      VG_(close)(RES);
+      SET_STATUS_Failure(VKI_EMFILE);
+   } else {
+      if (VG_(clo_track_fds)) {
+         ML_(record_fd_open_nameless)(tid, RES);
+      }
+   }
+}
 
 // SYS_membarrier 584 unimpl
 
@@ -7575,8 +7593,8 @@ const SyscallTableEntry ML_(syscall_table)[] = {
 #endif
 
 #if (FREEBSD_VERS >= FREEBSD_15)
-   // unimpl __NR_kqueuex             583
-   // unimpl __NR_kqueuex             584
+   BSDXY( __NR_kqueuex,         sys_kqueuex),           // 583
+   // unimpl __NR_membarrier          584
    BSDXY(__NR_timerfd_create,   sys_timerfd_create),    // 585
    BSDXY(__NR_timerfd_settime,  sys_timerfd_settime),   // 586
    BSDXY(__NR_timerfd_gettime,  sys_timerfd_gettime),   // 587
index f5b8386c67306c4ac9f6a0efb28408a601696222..5cccba91899ec04efb4e069f6bd4eae603b45302 100644 (file)
@@ -2,7 +2,8 @@
 include $(top_srcdir)/Makefile.tool-tests.am
 
 dist_noinst_SCRIPTS = filter_stderr filter_pts dump_stdout filter_sigwait \
-       filter_scalar filter_realpathat filter_fstat filter_eventfd2
+       filter_scalar filter_realpathat filter_fstat filter_eventfd2 \
+       toucher1 toucher2
 
 EXTRA_DIST = \
        access.vgtest \
@@ -12,6 +13,17 @@ EXTRA_DIST = \
        aligned_allocs_supp.vgtest \
        aligned_allocs_supp.stderr.exp \
        aligned_allocs_supp.supp \
+       bug464476.vgtest \
+       bug464476.stderr.exp \
+       bug464476.stdout.exp \
+       bug464476_abs_symlink.vgtest \
+       bug464476_abs_symlink.stderr.exp \
+       bug464476_abs_symlink.stdout.exp \
+       bug464476_rel_symlink.vgtest \
+       bug464476_rel_symlink.stderr.exp \
+       bug464476_rel_symlink.stdout.exp \
+       bug470713.vgtest bug470713.stderr.exp \
+               bug470713.stdout.exp \
        capsicum.vgtest \
        capsicum.stderr.exp \
        chflags.vgtest\
@@ -20,6 +32,10 @@ EXTRA_DIST = \
        chmod_chown.vgtest \
        chmod_chown.stderr.exp \
        close_range.vgtest close_range.stderr.exp \
+       delete_sized_mismatch.vgtest \
+       delete_sized_mismatch.stderr.exp \
+       delete_sized_mismatch_xml.vgtest \
+       delete_sized_mismatch_xml.stderr.exp \
        errno_aligned_allocs.vgtest \
        errno_aligned_allocs.stderr.exp \
        eventfd1.vgtest \
@@ -43,18 +59,33 @@ EXTRA_DIST = \
        getfsstat.stderr.exp \
        getfsstat.supp \
                getfsstat.stderr.exp-x86 \
+       kqueue.vgtest \
+       kqueue.stderr.exp \
+       kqueue.stdout.exp \
+       kqueuex.vgtest \
+       kqueuex.stderr.exp \
+       kqueuex.stdout.exp \
        linkat.vgtest \
        linkat.stderr.exp \
+        memalign.vgtest memalign.stderr.exp \
+       memalign_supp.vgtest memalign_supp.stderr.exp \
+       memalign_supp.supp \
        misc.vgtest \
        misc.stderr.exp \
        pdfork_pdkill.vgtest \
        pdfork_pdkill.stderr.exp \
+       realpathat.vgtest \
+       realpathat.stderr.exp \
        revoke.vgtest \
        revoke.stderr.exp \
        scalar.h scalar.vgtest \
        scalar.stderr.exp \
                scalar.stderr.exp-x86 \
        scalar_abort2.vgtest \
+       scalar_13_plus.vgtest \
+       scalar_13_plus.stderr.exp \
+       scalar_15_plus.vgtest \
+       scalar_15_plus.stderr.exp \
        scalar_abort2.stderr.exp \
        scalar_fork.vgtest \
        scalar_fork.stderr.exp \
@@ -64,18 +95,29 @@ EXTRA_DIST = \
        scalar_thr_exit.stderr.exp \
        scalar_vfork.vgtest \
        scalar_vfork.stderr.exp \
+       sctp.vgtest \
+       sctp.stderr.exp \
+       sctp.stdout.exp \
+       sctp2.vgtest \
+       sctp2.stderr.exp \
+       sctp2.stdout.exp \
+       setproctitle.vgtest \
+       setproctitle.stderr.exp \
+       setproctitle.stdout.exp \
        sigwait.vgtest \
        sigwait.stdout.exp \
        sigwait.stderr.exp \
                sigwait.stderr.exp-x86 \
+       stat.vgtest \
+       stat.stderr.exp \
+               stat.stderr.exp-x86 \
        statfs.vgtest \
        statfs.stderr.exp \
+       static_allocs.vgtest \
+       static_allocs.stderr.exp \
        supponlyobj.vgtest \
        supponlyobj.stderr.exp \
        supponlyobj.supp \
-       stat.vgtest \
-       stat.stderr.exp \
-               stat.stderr.exp-x86 \
        timerfd.vgtest \
        timerfd.stderr.exp \
        timerfd.stdout.exp \
@@ -83,51 +125,21 @@ EXTRA_DIST = \
        utimens.stderr.exp \
        utimes.vgtest \
        utimes.stderr.exp-x86 \
-       utimes.stderr.exp \
-       static_allocs.vgtest \
-       static_allocs.stderr.exp \
-       realpathat.vgtest \
-       realpathat.stderr.exp \
-       scalar_13_plus.vgtest \
-       scalar_13_plus.stderr.exp \
-       scalar_15_plus.vgtest \
-       scalar_15_plus.stderr.exp \
-       setproctitle.vgtest \
-       setproctitle.stderr.exp \
-       setproctitle.stdout.exp \
-       sctp.vgtest \
-       sctp.stderr.exp \
-       sctp.stdout.exp \
-       sctp2.vgtest \
-       sctp2.stderr.exp \
-       sctp2.stdout.exp \
-       bug464476.vgtest \
-       bug464476.stderr.exp \
-       bug464476.stdout.exp \
-       bug464476_abs_symlink.vgtest \
-       bug464476_abs_symlink.stderr.exp \
-       bug464476_abs_symlink.stdout.exp \
-       bug464476_rel_symlink.vgtest \
-       bug464476_rel_symlink.stderr.exp \
-       bug464476_rel_symlink.stdout.exp \
-        memalign.vgtest memalign.stderr.exp \
-       bug470713.vgtest bug470713.stderr.exp \
-               bug470713.stdout.exp \
-       memalign_supp.vgtest memalign_supp.stderr.exp \
-       memalign_supp.supp \
-       delete_sized_mismatch.vgtest \
-       delete_sized_mismatch.stderr.exp \
-       delete_sized_mismatch_xml.vgtest \
-       delete_sized_mismatch_xml.stderr.exp
+       utimes.stderr.exp
 
 check_PROGRAMS = \
+       access aligned_alloc bug464476 bug470713 capsicum \
+       chflags \
+       chmod_chown delete_sized_mismatch errno_aligned_allocs \
+       fexecve \
+       get_set_context get_set_login getfh \
+       kqueue linkat memalign misc \
        statfs pdfork_pdkill getfsstat inlinfo inlinfo_nested.so extattr \
-       sigwait chflags get_set_login revoke scalar capsicum getfh \
-       linkat scalar_fork scalar_thr_exit scalar_abort2 scalar_pdfork \
-       scalar_vfork stat file_locking_wait6 utimens access chmod_chown \
-       misc get_set_context utimes static_allocs fexecve errno_aligned_allocs \
-       setproctitle sctp sctp2 bug464476 memalign bug470713 \
-       aligned_alloc delete_sized_mismatch
+       sigwait revoke scalar \
+       scalar_fork scalar_thr_exit scalar_abort2 scalar_pdfork \
+       scalar_vfork stat file_locking_wait6 utimens \
+       utimes static_allocs \
+       setproctitle sctp sctp2 memalign
 
 AM_CFLAGS   += $(AM_FLAG_M3264_PRI)
 AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
@@ -149,7 +161,7 @@ scalar_13_plus_CFLAGS = ${AM_CFLAGS} -g
 endif
 
 if FREEBSD_VERS_15_PLUS
-check_PROGRAMS += scalar_15_plus timerfd
+check_PROGRAMS += kqueuex scalar_15_plus timerfd
 scalar_15_plus_CFLAGS = ${AM_CFLAGS} -g
 timerfd_LDFLAGS = -lm
 endif
diff --git a/memcheck/tests/freebsd/kqueue.c b/memcheck/tests/freebsd/kqueue.c
new file mode 100644 (file)
index 0000000..eac7b50
--- /dev/null
@@ -0,0 +1,54 @@
+#include <sys/event.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int
+main(int argc, char **argv)
+{
+    struct kevent event;    /* Event we want to monitor */
+    struct kevent tevent;   /* Event triggered */
+    int kq, fd, ret;
+
+    if (argc != 2)
+        err(EXIT_FAILURE, "Usage: %s path\n", argv[0]);
+    fd = open(argv[1], O_RDONLY);
+    if (fd == -1)
+        err(EXIT_FAILURE, "Failed to open '%s'", argv[1]);
+
+    /* Create kqueue. */
+    kq = kqueue();
+    if (kq == -1)
+        err(EXIT_FAILURE, "kqueue() failed");
+
+    /* Initialize kevent structure. */
+    EV_SET(&event, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE,
+        0, NULL);
+    /* Attach event to the kqueue. */
+    ret = kevent(kq, &event, 1, NULL, 0, NULL);
+    if (ret == -1)
+        err(EXIT_FAILURE, "kevent register");
+
+    for (;;) {
+        /* Sleep until something happens. */
+        ret = kevent(kq, NULL, 0, &tevent, 1, NULL);
+        if (ret == -1) {
+            err(EXIT_FAILURE, "kevent wait");
+        } else if (ret > 0) {
+            if (tevent.flags & EV_ERROR)
+                errx(EXIT_FAILURE, "Event error: %s", strerror(event.data));
+            else {
+                printf("Something was written in '%s'\n", argv[1]);
+                exit(0);
+           }
+        }
+    }
+
+    /* kqueues are destroyed upon close() */
+    (void)close(kq);
+    (void)close(fd);
+}
+
diff --git a/memcheck/tests/freebsd/kqueue.stderr.exp b/memcheck/tests/freebsd/kqueue.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/freebsd/kqueue.stdout.exp b/memcheck/tests/freebsd/kqueue.stdout.exp
new file mode 100644 (file)
index 0000000..fd64509
--- /dev/null
@@ -0,0 +1 @@
+Something was written in '/tmp/touch_file'
diff --git a/memcheck/tests/freebsd/kqueue.vgtest b/memcheck/tests/freebsd/kqueue.vgtest
new file mode 100644 (file)
index 0000000..ba1605a
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: ./toucher1
+prog: kqueue
+args: /tmp/touch_file
+vgopts: -q
diff --git a/memcheck/tests/freebsd/kqueuex.c b/memcheck/tests/freebsd/kqueuex.c
new file mode 100644 (file)
index 0000000..0f7cde7
--- /dev/null
@@ -0,0 +1,54 @@
+#include <sys/event.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int
+main(int argc, char **argv)
+{
+    struct kevent event;    /* Event we want to monitor */
+    struct kevent tevent;   /* Event triggered */
+    int kq, fd, ret;
+
+    if (argc != 2)
+        err(EXIT_FAILURE, "Usage: %s path\n", argv[0]);
+    fd = open(argv[1], O_RDONLY);
+    if (fd == -1)
+        err(EXIT_FAILURE, "Failed to open '%s'", argv[1]);
+
+    /* Create kqueue. */
+    kq = kqueuex(KQUEUE_CLOEXEC);
+    if (kq == -1)
+        err(EXIT_FAILURE, "kqueuex(KQUEUE_CLOEXEC) failed");
+
+    /* Initialize kevent structure. */
+    EV_SET(&event, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE,
+        0, NULL);
+    /* Attach event to the kqueue. */
+    ret = kevent(kq, &event, 1, NULL, 0, NULL);
+    if (ret == -1)
+        err(EXIT_FAILURE, "kevent register");
+
+    for (;;) {
+        /* Sleep until something happens. */
+        ret = kevent(kq, NULL, 0, &tevent, 1, NULL);
+        if (ret == -1) {
+            err(EXIT_FAILURE, "kevent wait");
+        } else if (ret > 0) {
+            if (tevent.flags & EV_ERROR)
+                errx(EXIT_FAILURE, "Event error: %s", strerror(event.data));
+            else {
+                printf("Something was written in '%s'\n", argv[1]);
+                exit(0);
+           }
+        }
+    }
+
+    /* kqueues are destroyed upon close() */
+    (void)close(kq);
+    (void)close(fd);
+}
+
diff --git a/memcheck/tests/freebsd/kqueuex.stderr.exp b/memcheck/tests/freebsd/kqueuex.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/freebsd/kqueuex.stdout.exp b/memcheck/tests/freebsd/kqueuex.stdout.exp
new file mode 100644 (file)
index 0000000..fd64509
--- /dev/null
@@ -0,0 +1 @@
+Something was written in '/tmp/touch_file'
diff --git a/memcheck/tests/freebsd/kqueuex.vgtest b/memcheck/tests/freebsd/kqueuex.vgtest
new file mode 100644 (file)
index 0000000..ba1605a
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: ./toucher1
+prog: kqueue
+args: /tmp/touch_file
+vgopts: -q
index cd40a20460abd74d73286a5b24fc835a30a53f80..2945060c2934b94d3a8d55cf0cda93bef550c536 100644 (file)
@@ -7,7 +7,8 @@ int main(void)
    x0 = px[0];
 
    /* SYS_kqueuex                        583 */
-   /* unimpl */
+   GO(SYS_kqueuex, " 1s 0m");
+   SY(SYS_kqueuex, x0+123); FAIL;
 
    /* SYS_membarrier                     584 */
    /* unimpl */
index 6c2ef077c463bb01a08f59283cb130215c41a0a1..5717326f32dd9dfa914abdcb0f369cf00c60d761 100644 (file)
@@ -1,3 +1,9 @@
+---------------------------------------------------------
+583:             SYS_kqueuex  1s 0m
+---------------------------------------------------------
+Syscall param kqueuex(flags) contains uninitialised byte(s)
+   ...
+
 ---------------------------------------------------------
 585:      SYS_timerfd_create  2s 0m
 ---------------------------------------------------------
diff --git a/memcheck/tests/freebsd/toucher1 b/memcheck/tests/freebsd/toucher1
new file mode 100755 (executable)
index 0000000..56b8df5
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# not sure if background tasks can be run from .vgtest
+# this just runs the next script in the background
+
+./toucher2&
diff --git a/memcheck/tests/freebsd/toucher2 b/memcheck/tests/freebsd/toucher2
new file mode 100755 (executable)
index 0000000..8544cb5
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# the kqueue(x) tests wait for kernel events, specifically
+# writes to a file
+# this runs in the background
+# and modifies a tmp file that the TC will be watching
+# tiny race condition between the touch and
+# the valgrinded binary starting to monitor the file
+
+touch /tmp/touch_file
+sleep 1
+
+echo hello >> /tmp/touch_file
+rm /tmp/touch_file