From 42d2e08f392acb5ede4b6c29ec7d17ce42fd35c8 Mon Sep 17 00:00:00 2001 From: alice Date: Thu, 27 Aug 2026 20:21:45 +0000 Subject: [PATCH] vms-706: build vms_stdio.c + vms_futex.c on VAX (close the freestanding-facility gap) The freestanding buffered-I/O (vms_stdio.c) and futex (vms_futex.c) facilities built on x86_64/aarch64/alpha but were ABSENT on VAX: the NetBSD syscall header omitted vms_sys_openat/vms_sys_futex and vms_types.h left VMS_FUTEX_* undefined on NetBSD, so both files were excluded from the netbsd build set -- any feature resting on them was silently VAX-absent. Converged (per the max-shared-code directive) by providing the wrappers, NOT fencing the feature off. * arch/vax/vms_syscall_netbsd.h: add vms_sys_openat (NetBSD libc openat(2); flags is the VMS_O_* mask) and vms_sys_futex. NetBSD ships no libc futex() wrapper -- the syscall is __futex (SYS___futex), a 7-arg form that inserts `val2` before val3 (unused by our WAIT/WAKE/WAIT_BITSET ops -> 0); called via syscall(SYS___futex, ...). The wrapper folds errno into a raw negative-errno return so vms_futex.c's vms_condvar_timedwait, which tests `ret == -VMS_ETIMEDOUT`, keeps working (the libc -1/errno convention would break timeout detection). * vms_types.h: add a __NetBSD__ branch defining VMS_FUTEX_* as aliases of FUTEX_* (substrate-correct, _Static_assert-checked -- never a transcribed Linux number, which is exactly what the prior "Linux-only" note guarded against). VMS_O_* was already NetBSD-mapped. * CMakeLists.txt: add vms_stdio.c + vms_futex.c to the netbsd VMSSYS_C_SOURCES. The Linux/host path is untouched (both additions are __NetBSD__-guarded), so host tests are unaffected. Proven: both TUs cross-compile clean to elf32-vax against the pinned NetBSD 10.1 sysroot (-Wall -Wextra, static-asserts pass, U openat / U syscall referenced) -- the vax-cmake-images CI gate now compiles them. Runtime SIMH verification of the futex wrapper deferred (host RAM-blocked); the __futex 7-arg ABI is verified against NetBSD syscalls.master. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/libvmssys/CMakeLists.txt | 10 ++++--- src/libvmssys/arch/vax/vms_syscall_netbsd.h | 31 +++++++++++++++++++++ src/libvmssys/vms_types.h | 30 ++++++++++++++------ 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/libvmssys/CMakeLists.txt b/src/libvmssys/CMakeLists.txt index e57859a0b..4374c6d63 100644 --- a/src/libvmssys/CMakeLists.txt +++ b/src/libvmssys/CMakeLists.txt @@ -52,15 +52,17 @@ if(VMSSYS_SUBSTRATE STREQUAL "netbsd") # Link-libc build set: substrate-agnostic VMS RTL + kif policy + NetBSD # transport leaf. Excluded on purpose (design §4.1): # * vms_runtime_init.c -- hand-rolled auxv/TLS; NetBSD csu/libc does it. - # * vms_stdio.c/vms_futex.c -- freestanding buffered-I/O + futex sync, - # superseded by NetBSD libc/libpthread; they also use VMS_O_*/futex - # wrappers whose per-substrate constant resolution is a deferred audit - # item (docs/design-ovmx-netbsd-syskrnl.md §4.2). # * kif_transport_linux.c -- replaced by kif_transport_netbsd.c. + # vms_stdio.c + vms_futex.c ARE built here now (vms-706): their VMS_O_*/futex + # wrappers resolve per-substrate (vms_sys_openat/vms_sys_futex over NetBSD + # openat(2)/__futex(2); VMS_O_*/VMS_FUTEX_* alias /), + # closing the freestanding-facility gap so the same sources build on VAX. set(VMSSYS_C_SOURCES vms_string.c vms_snprintf.c vms_math.c + vms_stdio.c + vms_futex.c vms_kif.c kif_transport_netbsd.c ) diff --git a/src/libvmssys/arch/vax/vms_syscall_netbsd.h b/src/libvmssys/arch/vax/vms_syscall_netbsd.h index f06ce3cc8..3b993ea7f 100644 --- a/src/libvmssys/arch/vax/vms_syscall_netbsd.h +++ b/src/libvmssys/arch/vax/vms_syscall_netbsd.h @@ -43,6 +43,8 @@ #include #include #include +#include /* openat (vms_sys_openat) -- vms-706 */ +#include /* SYS___futex (vms_sys_futex) -- vms-706 */ /* ================================================================ * Process @@ -113,6 +115,35 @@ static inline int vms_sys_ioctl(int fd, unsigned long request, unsigned long arg return ioctl(fd, request, (void *)(unsigned long)arg); } +/* vms-706: the freestanding buffered-I/O (vms_stdio.c) + futex (vms_futex.c) + * facilities. The VMS_O_ and VMS_FUTEX_ constants resolve to the NetBSD + * / values (vms_types.h substrate-select) -- never a + * transcribed Linux number. */ + +static inline int vms_sys_openat(int dirfd, const char *path, int flags, + vms_mode_t mode) +{ + /* NetBSD libc openat(2); flags is the VMS_O_* mask (== NetBSD O_*). */ + return openat(dirfd, path, flags, (mode_t)mode); +} + +static inline long vms_sys_futex(uint32_t *uaddr, int futex_op, uint32_t val, + const struct vms_timespec *timeout, + uint32_t *uaddr2, uint32_t val3) +{ + /* NetBSD ships no libc futex() wrapper -- the syscall is __futex + * (SYS___futex), a SEVEN-arg form that inserts `val2` before val3. Our ops + * (WAIT/WAKE/WAIT_BITSET) do not use val2, so it is 0. struct vms_timespec + * is layout-compatible with struct timespec on ILP32; cast explicitly. */ + long r = syscall(SYS___futex, (int *)uaddr, futex_op, (int)val, + (const struct timespec *)timeout, (int *)uaddr2, + 0 /* val2 */, (int)val3); + /* Fold errno into a raw negative-errno return: vms_futex.c's + * vms_condvar_timedwait tests `ret == -VMS_ETIMEDOUT`, so the libc + * -1/errno convention would break timeout detection. */ + return (r < 0) ? -(long)errno : r; +} + /* ================================================================ * Raw-return error helpers. On the raw-freestanding path a syscall returns * negative-errno; libc returns -1 and sets errno. These helpers exist so any diff --git a/src/libvmssys/vms_types.h b/src/libvmssys/vms_types.h index d0dfa475c..757bef535 100644 --- a/src/libvmssys/vms_types.h +++ b/src/libvmssys/vms_types.h @@ -640,16 +640,28 @@ struct vms_io_uring_params { /* ================================================================ * Futex operations * - * These are Linux futex(2) op numbers. They are deliberately NOT defined on the - * NetBSD substrate (rd vms-30a, audit item 5.2): NetBSD has no Linux-compatible - * futex ABI, the netbsd executive/lnm/mbx wait primitive is provided separately - * (design 4.2), and vms_futex.c (their only consumer) is excluded from the - * netbsd build set. Leaving Linux-numeric op values defined on NetBSD would be - * exactly the hardcoded-Linux-constant-reaching-a-NetBSD-syscall hazard this - * audit item exists to kill, so the whole block is Linux-only. + * futex(2) op numbers, substrate-selected like VMS_O_* above (vms-706). The op + * VALUES happen to match across Linux and NetBSD, but each substrate takes them + * from ITS OWN header so no transcribed magic number reaches the wrong syscall: + * Linux hardcodes the well-known futex(2) numbers; NetBSD aliases + * FUTEX_*, and vms_sys_futex (arch/vax/vms_syscall_netbsd.h) issues __futex(2). + * (Supersedes the earlier "deferred, NetBSD-excluded" audit note, rd vms-30a + * item 5.2: vms_futex.c is no longer excluded from the netbsd build.) * ================================================================ */ -#if !defined(__NetBSD__) +#if defined(__NetBSD__) +#include +#define VMS_FUTEX_WAIT FUTEX_WAIT +#define VMS_FUTEX_WAKE FUTEX_WAKE +#define VMS_FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) +#define VMS_FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) +#define VMS_FUTEX_WAIT_BITSET FUTEX_WAIT_BITSET +#define VMS_FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG) +#define VMS_FUTEX_BITSET_MATCH_ANY FUTEX_BITSET_MATCH_ANY +/* Prove the substrate-select took the NetBSD header value, not a stale copy. */ +_Static_assert(VMS_FUTEX_WAIT == FUTEX_WAIT, "VMS_FUTEX_WAIT must resolve to NetBSD FUTEX_WAIT"); +_Static_assert(VMS_FUTEX_WAIT_BITSET == FUTEX_WAIT_BITSET, "VMS_FUTEX_WAIT_BITSET must resolve to NetBSD FUTEX_WAIT_BITSET"); +#else #define VMS_FUTEX_WAIT 0 #define VMS_FUTEX_WAKE 1 #define VMS_FUTEX_WAIT_PRIVATE (VMS_FUTEX_WAIT | 128) @@ -657,7 +669,7 @@ struct vms_io_uring_params { #define VMS_FUTEX_WAIT_BITSET 9 #define VMS_FUTEX_WAIT_BITSET_PRIVATE (VMS_FUTEX_WAIT_BITSET | 128) #define VMS_FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF -#endif /* !__NetBSD__ */ +#endif /* __NetBSD__ */ /* ================================================================ * Auxiliary vector (from kernel ELF loader)