From b8a81558d844a9f00dafff3b5586624ded8993a1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 19 Oct 2024 05:50:30 -0700 Subject: [PATCH] Update versions of things in CI. Update to the latest nightly Rust, actions/cache, and QEMU patches from rustix, and remove unneeded `feature` declarations. --- .github/workflows/main.yml | 6 +- ci/more-sockopts.patch | 92 +++++++++++++ ci/pidfd-open.patch | 19 +++ ci/select-setsize.patch | 269 +++++++++++++++++++++++++++++++++++++ ci/tiocgsid.patch | 17 +++ rust-toolchain.toml | 2 +- tests/examples.rs | 2 +- tests/stdtests.rs | 4 - 8 files changed, 404 insertions(+), 7 deletions(-) create mode 100644 ci/more-sockopts.patch create mode 100644 ci/pidfd-open.patch create mode 100644 ci/select-setsize.patch create mode 100644 ci/tiocgsid.patch diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4f15af9..91b5b48 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,7 +58,7 @@ jobs: rustup target add ${{ matrix.target }} if: matrix.target != '' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ${{ runner.tool_cache }}/qemu key: qemu-${{ matrix.target }}-${{ env.QEMU_BUILD_VERSION }}-patched @@ -107,6 +107,10 @@ jobs: patch -p1 < $GITHUB_WORKSPACE/ci/s390x-stat-have-nsec.patch patch -p1 < $GITHUB_WORKSPACE/ci/aarch64-o-largefile.patch patch -p1 < $GITHUB_WORKSPACE/ci/tcgets2-tcsets2.patch + patch -p1 < $GITHUB_WORKSPACE/ci/tiocgsid.patch + patch -p1 < $GITHUB_WORKSPACE/ci/more-sockopts.patch + patch -p1 < $GITHUB_WORKSPACE/ci/pidfd-open.patch + patch -p1 < $GITHUB_WORKSPACE/ci/select-setsize.patch ./configure --target-list=${{ matrix.qemu_target }} --prefix=${{ runner.tool_cache }}/qemu --disable-tools --disable-slirp --disable-fdt --disable-capstone --disable-docs ninja -C build install if: matrix.qemu != '' && matrix.os == 'ubuntu-latest' diff --git a/ci/more-sockopts.patch b/ci/more-sockopts.patch new file mode 100644 index 0000000..5afdcb0 --- /dev/null +++ b/ci/more-sockopts.patch @@ -0,0 +1,92 @@ +From Dan Gohman +Subject: [PATCH] Implement various socket options. + +This implements the `SO_INCOMING_CPU`, `SO_COOKIE`, and `SO_PROTOCOL` +socket options. + +diff -ur -x roms -x build a/linux-user/generic/sockbits.h b/linux-user/generic/sockbits.h +--- a/linux-user/generic/sockbits.h ++++ b/linux-user/generic/sockbits.h +@@ -60,4 +60,10 @@ + + #define TARGET_SO_PROTOCOL 38 + #define TARGET_SO_DOMAIN 39 ++#ifndef TARGET_SO_INCOMING_CPU ++#define TARGET_SO_INCOMING_CPU 49 ++#endif ++#ifndef TARGET_SO_COOKIE ++#define TARGET_SO_COOKIE 57 ++#endif + #endif +diff -ur -x roms -x build a/linux-user/mips/sockbits.h b/linux-user/mips/sockbits.h +--- a/linux-user/mips/sockbits.h ++++ b/linux-user/mips/sockbits.h +@@ -73,6 +73,9 @@ + #define TARGET_SO_RCVBUFFORCE 33 + #define TARGET_SO_PASSSEC 34 + ++#define TARGET_SO_INCOMING_CPU 49 ++#define TARGET_SO_COOKIE 57 ++ + /** sock_type - Socket types + * + * Please notice that for binary compat reasons MIPS has to +diff -ur -x roms -x build a/linux-user/syscall.c b/linux-user/syscall.c +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -2476,6 +2476,9 @@ + case TARGET_SO_RCVLOWAT: + optname = SO_RCVLOWAT; + break; ++ case TARGET_SO_INCOMING_CPU: ++ optname = SO_INCOMING_CPU; ++ break; + default: + goto unimplemented; + } +@@ -2534,6 +2537,7 @@ + { + abi_long ret; + int len, val; ++ int64_t val64; + socklen_t lv; + + switch(level) { +@@ -2733,6 +2737,27 @@ + case TARGET_SO_DOMAIN: + optname = SO_DOMAIN; + goto int_case; ++ case TARGET_SO_INCOMING_CPU: ++ optname = SO_INCOMING_CPU; ++ goto int_case; ++ case TARGET_SO_COOKIE: ++ optname = SO_COOKIE; ++ if (get_user_u32(len, optlen)) ++ return -TARGET_EFAULT; ++ if (len < 0) ++ return -TARGET_EINVAL; ++ lv = sizeof(val64); ++ ret = get_errno(getsockopt(sockfd, level, optname, &val64, &lv)); ++ if (ret < 0) ++ return ret; ++ if (len > lv) ++ len = lv; ++ assert(len == 8); ++ if (put_user_u64(val64, optval_addr)) ++ return -TARGET_EFAULT; ++ if (put_user_u32(len, optlen)) ++ return -TARGET_EFAULT; ++ break; + default: + goto int_case; + } +@@ -2756,6 +2781,9 @@ + case SO_ERROR: + val = host_to_target_errno(val); + break; ++ case SO_PROTOCOL: ++ val = host_to_target_errno(val); ++ break; + } + if (level == SOL_SOCKET && optname == SO_ERROR) { + val = host_to_target_errno(val); diff --git a/ci/pidfd-open.patch b/ci/pidfd-open.patch new file mode 100644 index 0000000..6dcae96 --- /dev/null +++ b/ci/pidfd-open.patch @@ -0,0 +1,19 @@ +From Dan Gohman +Subject: [PATCH] Fix the flags argument of `pidfd_open`. + +This corrects the flags value of `pidfd_open` to avoid passing +target flags to the host. Currently the only flag is `PIDFD_NONBLOCK` +so we use the `fcntl_flags_tbl` to translate it. + +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -9477,7 +9477,8 @@ + #endif + #if defined(__NR_pidfd_open) && defined(TARGET_NR_pidfd_open) + case TARGET_NR_pidfd_open: +- return get_errno(pidfd_open(arg1, arg2)); ++ return get_errno(pidfd_open(arg1, ++ target_to_host_bitmask(arg2, fcntl_flags_tbl))); + #endif + #if defined(__NR_pidfd_send_signal) && defined(TARGET_NR_pidfd_send_signal) + case TARGET_NR_pidfd_send_signal: diff --git a/ci/select-setsize.patch b/ci/select-setsize.patch new file mode 100644 index 0000000..48f9824 --- /dev/null +++ b/ci/select-setsize.patch @@ -0,0 +1,269 @@ +From Dan Gohman +Subject: [PATCH] Remove the `FD_SETSIZE` limitation in `select` + +The `fd_set` type is limited to a fixed `FD_SETSIZE` number of file +descriptors, however Linux's `select has no such limitation. Change +the `select` implementation to using manual bit-vector logic to better +implement the Linux semantics. + +diff -ur a/linux-user/syscall.c b/linux-user/syscall.c +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -664,8 +664,9 @@ + char **, argv, char **, envp, int, flags) + #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \ + defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64) +-safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \ +- fd_set *, exceptfds, struct timespec *, timeout, void *, sig) ++safe_syscall6(int, pselect6, int, nfds, unsigned long *, readfds, \ ++ unsigned long *, writefds, unsigned long *, exceptfds, \ ++ struct timespec *, timeout, void *, sig) + #endif + #if defined(TARGET_NR_ppoll) || defined(TARGET_NR_ppoll_time64) + safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds, +@@ -861,7 +862,7 @@ + + #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \ + defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64) +-static inline abi_long copy_from_user_fdset(fd_set *fds, ++static inline abi_long copy_from_user_fdset(unsigned long *fds, + abi_ulong target_fds_addr, + int n) + { +@@ -875,7 +876,8 @@ + 1))) + return -TARGET_EFAULT; + +- FD_ZERO(fds); ++ memset(fds, 0, DIV_ROUND_UP(n, sizeof(unsigned long) * 8) * ++ sizeof(unsigned long)); + k = 0; + for (i = 0; i < nw; i++) { + /* grab the abi_ulong */ +@@ -883,7 +885,8 @@ + for (j = 0; j < TARGET_ABI_BITS; j++) { + /* check the bit inside the abi_ulong */ + if ((b >> j) & 1) +- FD_SET(k, fds); ++ fds[k / (sizeof(unsigned long) * 8)] |= ++ 1ul << (k % (sizeof(unsigned long) * 8)); + k++; + } + } +@@ -893,7 +896,8 @@ + return 0; + } + +-static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr, ++static inline abi_ulong copy_from_user_fdset_ptr(unsigned long *fds, ++ unsigned long **fds_ptr, + abi_ulong target_fds_addr, + int n) + { +@@ -908,7 +912,7 @@ + } + + static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr, +- const fd_set *fds, ++ const unsigned long *fds, + int n) + { + int i, nw, j, k; +@@ -926,7 +930,10 @@ + for (i = 0; i < nw; i++) { + v = 0; + for (j = 0; j < TARGET_ABI_BITS; j++) { +- v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j); ++ bool set = ++ (fds[k / (sizeof(unsigned long) * 8)] & ++ (1ul << (k % (sizeof(unsigned long) * 8)))) != 0; ++ v |= ((abi_ulong)set << j); + k++; + } + __put_user(v, &target_fds[i]); +@@ -1295,28 +1302,40 @@ + abi_ulong rfd_addr, abi_ulong wfd_addr, + abi_ulong efd_addr, abi_ulong target_tv_addr) + { +- fd_set rfds, wfds, efds; +- fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; ++ unsigned long *rfds, *wfds, *efds; ++ unsigned long *rfds_ptr, *wfds_ptr, *efds_ptr; + struct timeval tv; + struct timespec ts, *ts_ptr; + abi_long ret; + +- ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); ++ rfds = malloc(DIV_ROUND_UP(n, sizeof(unsigned long) * 8) * ++ sizeof(unsigned long)); ++ wfds = malloc(DIV_ROUND_UP(n, sizeof(unsigned long) * 8) * ++ sizeof(unsigned long)); ++ efds = malloc(DIV_ROUND_UP(n, sizeof(unsigned long) * 8) * ++ sizeof(unsigned long)); ++ ++ ret = copy_from_user_fdset_ptr(rfds, &rfds_ptr, rfd_addr, n); + if (ret) { ++ free(rfds); free(wfds); free(efds); + return ret; + } +- ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); ++ ret = copy_from_user_fdset_ptr(wfds, &wfds_ptr, wfd_addr, n); + if (ret) { ++ free(rfds); free(wfds); free(efds); + return ret; + } +- ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); ++ ret = copy_from_user_fdset_ptr(efds, &efds_ptr, efd_addr, n); + if (ret) { ++ free(rfds); free(wfds); free(efds); + return ret; + } + + if (target_tv_addr) { +- if (copy_from_user_timeval(&tv, target_tv_addr)) ++ if (copy_from_user_timeval(&tv, target_tv_addr)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; ++ } + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + ts_ptr = &ts; +@@ -1328,22 +1347,30 @@ + ts_ptr, NULL)); + + if (!is_error(ret)) { +- if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) ++ if (rfd_addr && copy_to_user_fdset(rfd_addr, rfds, n)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; +- if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) ++ } ++ if (wfd_addr && copy_to_user_fdset(wfd_addr, wfds, n)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; +- if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) ++ } ++ if (efd_addr && copy_to_user_fdset(efd_addr, efds, n)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; ++ } + + if (target_tv_addr) { + tv.tv_sec = ts.tv_sec; + tv.tv_usec = ts.tv_nsec / 1000; + if (copy_to_user_timeval(target_tv_addr, &tv)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } + } + } + ++ free(rfds); free(wfds); free(efds); + return ret; + } + +@@ -1377,8 +1404,8 @@ + bool time64) + { + abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr; +- fd_set rfds, wfds, efds; +- fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; ++ unsigned long *rfds, *wfds, *efds; ++ unsigned long *rfds_ptr, *wfds_ptr, *efds_ptr; + struct timespec ts, *ts_ptr; + abi_long ret; + +@@ -1399,16 +1426,26 @@ + efd_addr = arg4; + ts_addr = arg5; + +- ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); ++ rfds = malloc(DIV_ROUND_UP(n, sizeof(unsigned long) * 8) * ++ sizeof(unsigned long)); ++ wfds = malloc(DIV_ROUND_UP(n, sizeof(unsigned long) * 8) * ++ sizeof(unsigned long)); ++ efds = malloc(DIV_ROUND_UP(n, sizeof(unsigned long) * 8) * ++ sizeof(unsigned long)); ++ ++ ret = copy_from_user_fdset_ptr(rfds, &rfds_ptr, rfd_addr, n); + if (ret) { ++ free(rfds); free(wfds); free(efds); + return ret; + } +- ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); ++ ret = copy_from_user_fdset_ptr(wfds, &wfds_ptr, wfd_addr, n); + if (ret) { ++ free(rfds); free(wfds); free(efds); + return ret; + } +- ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); ++ ret = copy_from_user_fdset_ptr(efds, &efds_ptr, efd_addr, n); + if (ret) { ++ free(rfds); free(wfds); free(efds); + return ret; + } + +@@ -1419,10 +1456,12 @@ + if (ts_addr) { + if (time64) { + if (target_to_host_timespec64(&ts, ts_addr)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } + } else { + if (target_to_host_timespec(&ts, ts_addr)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } + } +@@ -1436,6 +1475,7 @@ + if (arg6) { + arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1); + if (!arg7) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } + arg_sigset = tswapal(arg7[0]); +@@ -1445,6 +1485,7 @@ + if (arg_sigset) { + ret = process_sigsuspend_mask(&sig.set, arg_sigset, arg_sigsize); + if (ret != 0) { ++ free(rfds); free(wfds); free(efds); + return ret; + } + sig_ptr = &sig; +@@ -1460,25 +1501,31 @@ + } + + if (!is_error(ret)) { +- if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) { ++ if (rfd_addr && copy_to_user_fdset(rfd_addr, rfds, n)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } +- if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) { ++ if (wfd_addr && copy_to_user_fdset(wfd_addr, wfds, n)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } +- if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) { ++ if (efd_addr && copy_to_user_fdset(efd_addr, efds, n)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } + if (time64) { + if (ts_addr && host_to_target_timespec64(ts_addr, &ts)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } + } else { + if (ts_addr && host_to_target_timespec(ts_addr, &ts)) { ++ free(rfds); free(wfds); free(efds); + return -TARGET_EFAULT; + } + } + } ++ free(rfds); free(wfds); free(efds); + return ret; + } + #endif diff --git a/ci/tiocgsid.patch b/ci/tiocgsid.patch new file mode 100644 index 0000000..01ccdf7 --- /dev/null +++ b/ci/tiocgsid.patch @@ -0,0 +1,17 @@ +From Dan Gohman +Subject: [PATCH] Fix the definition of `TIOCGSID`. + +This corrects the value of `TIOCGSID`. + +diff -ur a/linux-user/ioctls.h b/linux-user/ioctls.h +--- a/linux-user/ioctls.h ++++ b/linux-user/ioctls.h +@@ -22,7 +28,7 @@ + IOCTL(TIOCSCTTY, 0, TYPE_INT) + IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) +- IOCTL(TIOCGSID, IOC_W, MK_PTR(TYPE_INT)) ++ IOCTL(TIOCGSID, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT)) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index c69e020..ef919a1 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-10-06" +channel = "nightly-2024-10-15" components = ["rustc", "cargo", "rust-std", "rust-src", "rustfmt"] diff --git a/tests/examples.rs b/tests/examples.rs index f1fd8c1..960dde4 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -39,7 +39,7 @@ fn test_example(name: &str, features: &str, stdout: &str, stderr: &str) { let mut command = Command::new("cargo"); if which::which("rustup").is_ok() { - command.arg("+nightly-2024-10-06"); + command.arg("+nightly-2024-10-15"); } command.arg("run").arg("--quiet"); if !features.is_empty() { diff --git a/tests/stdtests.rs b/tests/stdtests.rs index 229a364..8b285d5 100644 --- a/tests/stdtests.rs +++ b/tests/stdtests.rs @@ -1,12 +1,8 @@ #![feature(cfg_target_has_atomic)] -#![feature(const_ip)] -#![feature(const_ipv4)] -#![feature(const_ipv6)] #![feature(core_io_borrowed_buf)] #![feature(duration_constants)] #![feature(io_error_uncategorized)] #![feature(ip)] -#![feature(lazy_cell)] #![feature(maybe_uninit_uninit_array)] #![feature(once_cell_try)] #![feature(read_buf)]