From: Paul Floyd Date: Sun, 17 Sep 2023 09:06:05 +0000 (+0200) Subject: FreeBSD: Add syscall wrapper for kqueuex (FreeBSD 15) X-Git-Tag: VALGRIND_3_22_0~62 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=410adb9b0a9793bc403caf4fdb26fbbae2adc4cd;p=thirdparty%2Fvalgrind.git FreeBSD: Add syscall wrapper for kqueuex (FreeBSD 15) --- diff --git a/.gitignore b/.gitignore index 76fd2f261b..44533e66fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1366,6 +1366,8 @@ /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 b4a9dfd1e4..736e33baf5 100644 --- 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 =================== diff --git a/coregrind/m_syswrap/priv_syswrap-freebsd.h b/coregrind/m_syswrap/priv_syswrap-freebsd.h index 79e52b9fdf..b02d9fb4a5 100644 --- a/coregrind/m_syswrap/priv_syswrap-freebsd.h +++ b/coregrind/m_syswrap/priv_syswrap-freebsd.h @@ -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 diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index ffe12ef799..fda60920c2 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -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 diff --git a/memcheck/tests/freebsd/Makefile.am b/memcheck/tests/freebsd/Makefile.am index f5b8386c67..5cccba9189 100644 --- a/memcheck/tests/freebsd/Makefile.am +++ b/memcheck/tests/freebsd/Makefile.am @@ -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 index 0000000000..eac7b50a24 --- /dev/null +++ b/memcheck/tests/freebsd/kqueue.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include + +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 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/freebsd/kqueue.stdout.exp b/memcheck/tests/freebsd/kqueue.stdout.exp new file mode 100644 index 0000000000..fd64509f07 --- /dev/null +++ b/memcheck/tests/freebsd/kqueue.stdout.exp @@ -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 index 0000000000..ba1605ab32 --- /dev/null +++ b/memcheck/tests/freebsd/kqueue.vgtest @@ -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 index 0000000000..0f7cde7b85 --- /dev/null +++ b/memcheck/tests/freebsd/kqueuex.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include + +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 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/freebsd/kqueuex.stdout.exp b/memcheck/tests/freebsd/kqueuex.stdout.exp new file mode 100644 index 0000000000..fd64509f07 --- /dev/null +++ b/memcheck/tests/freebsd/kqueuex.stdout.exp @@ -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 index 0000000000..ba1605ab32 --- /dev/null +++ b/memcheck/tests/freebsd/kqueuex.vgtest @@ -0,0 +1,4 @@ +prereq: ./toucher1 +prog: kqueue +args: /tmp/touch_file +vgopts: -q diff --git a/memcheck/tests/freebsd/scalar_15_plus.c b/memcheck/tests/freebsd/scalar_15_plus.c index cd40a20460..2945060c29 100644 --- a/memcheck/tests/freebsd/scalar_15_plus.c +++ b/memcheck/tests/freebsd/scalar_15_plus.c @@ -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 */ diff --git a/memcheck/tests/freebsd/scalar_15_plus.stderr.exp b/memcheck/tests/freebsd/scalar_15_plus.stderr.exp index 6c2ef077c4..5717326f32 100644 --- a/memcheck/tests/freebsd/scalar_15_plus.stderr.exp +++ b/memcheck/tests/freebsd/scalar_15_plus.stderr.exp @@ -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 index 0000000000..56b8df5dff --- /dev/null +++ b/memcheck/tests/freebsd/toucher1 @@ -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 index 0000000000..8544cb57a5 --- /dev/null +++ b/memcheck/tests/freebsd/toucher2 @@ -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