From ebe5a916b08d5d58b03fe551a95038d9cf964781 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 26 May 2020 00:18:47 -0400 Subject: [PATCH 01/16] Properly encode AnonConst into crate metadata Fixes #68104 Previous, we were encoding AnonConst as a regular Const, causing us to treat them differently after being deserialized in another compilation session. --- src/librustc_metadata/rmeta/decoder.rs | 8 ++++++-- src/librustc_metadata/rmeta/encoder.rs | 2 +- src/librustc_metadata/rmeta/mod.rs | 1 + src/test/ui/const-generics/auxiliary/impl-const.rs | 9 +++++++++ .../issue-68104-print-stack-overflow.rs | 14 ++++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/const-generics/auxiliary/impl-const.rs create mode 100644 src/test/ui/const-generics/issue-68104-print-stack-overflow.rs diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 2b292b35c159d..79c4c5214a60e 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -564,6 +564,7 @@ impl MetadataBlob { impl EntryKind { fn def_kind(&self) -> DefKind { match *self { + EntryKind::AnonConst(..) => DefKind::AnonConst, EntryKind::Const(..) => DefKind::Const, EntryKind::AssocConst(..) => DefKind::AssocConst, EntryKind::ImmStatic @@ -1121,7 +1122,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn mir_const_qualif(&self, id: DefIndex) -> mir::ConstQualifs { match self.kind(id) { - EntryKind::Const(qualif, _) + EntryKind::AnonConst(qualif, _) + | EntryKind::Const(qualif, _) | EntryKind::AssocConst( AssocContainer::ImplDefault | AssocContainer::ImplFinal @@ -1341,7 +1343,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn get_rendered_const(&self, id: DefIndex) -> String { match self.kind(id) { - EntryKind::Const(_, data) | EntryKind::AssocConst(_, _, data) => data.decode(self).0, + EntryKind::AnonConst(_, data) + | EntryKind::Const(_, data) + | EntryKind::AssocConst(_, _, data) => data.decode(self).0, _ => bug!(), } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 91fbfcc0133eb..25166dd79028a 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1342,7 +1342,7 @@ impl EncodeContext<'tcx> { let const_data = self.encode_rendered_const_for_body(body_id); let qualifs = self.tcx.mir_const_qualif(def_id); - record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Const(qualifs, const_data)); + record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst(qualifs, const_data)); record!(self.tables.visibility[def_id.to_def_id()] <- ty::Visibility::Public); record!(self.tables.span[def_id.to_def_id()] <- self.tcx.def_span(def_id)); self.encode_item_type(def_id.to_def_id()); diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 89d525eb80b8c..91febbcee10c1 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -281,6 +281,7 @@ define_tables! { #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] enum EntryKind { + AnonConst(mir::ConstQualifs, Lazy), Const(mir::ConstQualifs, Lazy), ImmStatic, MutStatic, diff --git a/src/test/ui/const-generics/auxiliary/impl-const.rs b/src/test/ui/const-generics/auxiliary/impl-const.rs new file mode 100644 index 0000000000000..fc993d63927c3 --- /dev/null +++ b/src/test/ui/const-generics/auxiliary/impl-const.rs @@ -0,0 +1,9 @@ +#![feature(const_generics)] + +pub struct Num; + +// Braces around const expression causes crash +impl Num<{5}> { + pub fn five(&self) { + } +} diff --git a/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs b/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs new file mode 100644 index 0000000000000..bda9ce8767d08 --- /dev/null +++ b/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs @@ -0,0 +1,14 @@ +// aux-build:impl-const.rs +// run-pass + +#![feature(const_generics)] +#![allow(incomplete_features)] + +extern crate impl_const; + +use impl_const::*; + +pub fn main() { + let n = Num::<5>; + n.five(); +} From a008a55ff680ec600b5617d6a1f1701450aa8911 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Mon, 18 May 2020 14:56:34 +0100 Subject: [PATCH 02/16] Add a disabled builder for riscv64 emulated tests This will run all tests for `riscv64gc-unknown-linux-gnu` in a QEMU instance. This is based upon the armhf QEMU test image. --- src/bootstrap/configure.py | 2 + .../0001-Remove-stime-function-calls.patch | 96 +++++++++++++++++ .../disabled/riscv64gc-linux/Dockerfile | 102 ++++++++++++++++++ .../disabled/riscv64gc-linux/linux.config | 51 +++++++++ src/tools/remote-test-client/src/main.rs | 83 +++++++++++--- 5 files changed, 319 insertions(+), 15 deletions(-) create mode 100644 src/ci/docker/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch create mode 100644 src/ci/docker/disabled/riscv64gc-linux/Dockerfile create mode 100644 src/ci/docker/disabled/riscv64gc-linux/linux.config diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index d1e53db573e4c..47673ce1e8703 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -141,6 +141,8 @@ def v(*args): "rootfs in qemu testing, you probably don't want to use this") v("qemu-aarch64-rootfs", "target.aarch64-unknown-linux-gnu.qemu-rootfs", "rootfs in qemu testing, you probably don't want to use this") +v("qemu-riscv64-rootfs", "target.riscv64gc-unknown-linux-gnu.qemu-rootfs", + "rootfs in qemu testing, you probably don't want to use this") v("experimental-targets", "llvm.experimental-targets", "experimental LLVM targets to build") v("release-channel", "rust.channel", "the name of the release channel to build") diff --git a/src/ci/docker/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch b/src/ci/docker/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch new file mode 100644 index 0000000000000..08d0c5b2cac1e --- /dev/null +++ b/src/ci/docker/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch @@ -0,0 +1,96 @@ +From c820da85c65c7f3aa9e9cb3ed71ada69bf9b783e Mon Sep 17 00:00:00 2001 +From: Alistair Francis +Date: Tue, 19 Nov 2019 13:06:40 +0100 +Subject: [PATCH] Remove stime() function calls + +stime() has been deprecated in glibc 2.31 and replaced with +clock_settime(). Let's replace the stime() function calls with +clock_settime() in preperation. + +function old new delta +rdate_main 197 224 +27 +clock_settime - 27 +27 +date_main 926 941 +15 +stime 37 - -37 +------------------------------------------------------------------------------ +(add/remove: 2/2 grow/shrink: 2/0 up/down: 69/-37) Total: 32 bytes + +Signed-off-by: Alistair Francis +Signed-off-by: Denys Vlasenko + +[Tom Eccles: adjust patch context to apply on top of 1.31.1-stable] +Signed-off-by: Tom Eccles +--- + coreutils/date.c | 6 +++++- + libbb/missing_syscalls.c | 8 -------- + util-linux/rdate.c | 8 ++++++-- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/coreutils/date.c b/coreutils/date.c +index 3414d38ae..4ade6abb4 100644 +--- a/coreutils/date.c ++++ b/coreutils/date.c +@@ -279,6 +279,9 @@ int date_main(int argc UNUSED_PARAM, char **argv) + time(&ts.tv_sec); + #endif + } ++#if !ENABLE_FEATURE_DATE_NANO ++ ts.tv_nsec = 0; ++#endif + localtime_r(&ts.tv_sec, &tm_time); + + /* If date string is given, update tm_time, and maybe set date */ +@@ -301,9 +304,10 @@ int date_main(int argc UNUSED_PARAM, char **argv) + if (date_str[0] != '@') + tm_time.tm_isdst = -1; + ts.tv_sec = validate_tm_time(date_str, &tm_time); ++ ts.tv_nsec = 0; + + /* if setting time, set it */ +- if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) { ++ if ((opt & OPT_SET) && clock_settime(CLOCK_REALTIME, &ts) < 0) { + bb_perror_msg("can't set date"); + } + } +diff --git a/libbb/missing_syscalls.c b/libbb/missing_syscalls.c +index 87cf59b3d..dc40d9155 100644 +--- a/libbb/missing_syscalls.c ++++ b/libbb/missing_syscalls.c +@@ -15,14 +15,6 @@ pid_t getsid(pid_t pid) + return syscall(__NR_getsid, pid); + } + +-int stime(const time_t *t) +-{ +- struct timeval tv; +- tv.tv_sec = *t; +- tv.tv_usec = 0; +- return settimeofday(&tv, NULL); +-} +- + int sethostname(const char *name, size_t len) + { + return syscall(__NR_sethostname, name, len); +diff --git a/util-linux/rdate.c b/util-linux/rdate.c +index 70f829e7f..878375d78 100644 +--- a/util-linux/rdate.c ++++ b/util-linux/rdate.c +@@ -95,9 +95,13 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) + if (!(flags & 2)) { /* no -p (-s may be present) */ + if (time(NULL) == remote_time) + bb_error_msg("current time matches remote time"); +- else +- if (stime(&remote_time) < 0) ++ else { ++ struct timespec ts; ++ ts.tv_sec = remote_time; ++ ts.tv_nsec = 0; ++ if (clock_settime(CLOCK_REALTIME, &ts) < 0) + bb_perror_msg_and_die("can't set time of day"); ++ } + } + + if (flags != 1) /* not lone -s */ +-- +2.25.1 + diff --git a/src/ci/docker/disabled/riscv64gc-linux/Dockerfile b/src/ci/docker/disabled/riscv64gc-linux/Dockerfile new file mode 100644 index 0000000000000..f21dc2ba309b8 --- /dev/null +++ b/src/ci/docker/disabled/riscv64gc-linux/Dockerfile @@ -0,0 +1,102 @@ +# based on armhf-gnu/Dockerfile +FROM ubuntu:20.04 + +RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections +RUN apt-get update -y && apt-get install -y --no-install-recommends \ + bc \ + bison \ + ca-certificates \ + cmake \ + cpio \ + curl \ + debian-ports-archive-keyring \ + debootstrap \ + flex \ + gcc \ + gcc-riscv64-linux-gnu \ + git \ + g++-riscv64-linux-gnu \ + g++ \ + libc6-dev \ + libc6-dev-riscv64-cross \ + make \ + patch \ + python3 \ + qemu-system-misc \ + xz-utils + +ENV ARCH=riscv +ENV CROSS_COMPILE=riscv64-linux-gnu- + +WORKDIR /build + +# From https://github.com/michaeljclark/busybear-linux/blob/master/conf/linux.config +COPY riscv64gc-linux/linux.config /build + +# Compile the kernel that we're going to be emulating with. This is +# basically just done to be compatible with the QEMU target that we're going +# to be using when running tests. +RUN curl https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.6.16.tar.xz | tar xJf - && \ + cp linux.config linux-5.6.16/.config && \ + cd /build/linux-5.6.16 && \ + make olddefconfig && \ + make -j$(nproc) vmlinux +RUN cp linux-5.6.16/vmlinux /tmp +RUN rm -rf linux-5.6.16 + +# Compile an instance of busybox as this provides a lightweight system and init +# binary which we will boot into. Only trick here is configuring busybox to +# build static binaries. +RUN curl https://busybox.net/downloads/busybox-1.31.1.tar.bz2 | tar xjf - +COPY riscv64gc-linux/0001-Remove-stime-function-calls.patch /build/busybox-1.31.1/ +RUN cd /build/busybox-1.31.1 && \ + patch -p1 -i 0001-Remove-stime-function-calls.patch && \ + make defconfig && \ + sed -i 's/.*CONFIG_STATIC.*/CONFIG_STATIC=y/' .config && \ + make -j$(nproc) && \ + make install && \ + mv _install /tmp/rootfs && \ + cd /build && \ + rm -rf busybox-1.31.1 + +# Download the ubuntu rootfs, which we'll use as a chroot for all our tests +# This is only needed to provide /lib/* and /usr/lib/* +WORKDIR /tmp +RUN debootstrap --variant=minbase --arch=riscv64 --foreign focal /tmp/rootfs/ubuntu +RUN cd rootfs && mkdir proc sys dev etc etc/init.d +# rootfs/ubuntu/proc is in a weird state (access fails with ELOOP) until +# rootfs/ubuntu/debootstrap/debootstrap --second-stage is run (under emulation), +# but this takes ages. Instead hack it into a good enough state. +# /proc is used by std::env::current_exe() (which is roughly +# `readlink /proc/self/exe`) +RUN cd rootfs/ubuntu && rm -rf proc && mkdir proc + +# Copy over our init script, which starts up our test server and also a few other +# misc tasks +COPY scripts/qemu-bare-bones-rcS rootfs/etc/init.d/rcS +RUN chmod +x rootfs/etc/init.d/rcS + +# Helper to quickly fill the entropy pool in the kernel +COPY scripts/qemu-bare-bones-addentropy.c /tmp/addentropy.c +RUN riscv64-linux-gnu-gcc addentropy.c -o rootfs/addentropy -static + +# download and build the riscv bootloader +RUN git clone https://github.com/riscv/riscv-pk +WORKDIR /tmp/riscv-pk +# nothing special about this revision: it is just master at the time of writing +# v1.0.0 doesn't build +RUN git checkout 5d9ed238e1cabfbca3c47f50d32894ce94bfc304 +RUN mkdir build && cd build && \ + ../configure --with-payload=/tmp/vmlinux --host=riscv64-linux-gnu && \ + make -j$(nproc) && \ + cp bbl /tmp +WORKDIR /tmp +RUN rm -rf /tmp/riscv-pk + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV RUST_CONFIGURE_ARGS --qemu-riscv64-rootfs=/tmp/rootfs +ENV SCRIPT python3 ../x.py test --target riscv64gc-unknown-linux-gnu + +ENV NO_CHANGE_USER=1 diff --git a/src/ci/docker/disabled/riscv64gc-linux/linux.config b/src/ci/docker/disabled/riscv64gc-linux/linux.config new file mode 100644 index 0000000000000..5142664742f20 --- /dev/null +++ b/src/ci/docker/disabled/riscv64gc-linux/linux.config @@ -0,0 +1,51 @@ +CONFIG_DEFAULT_HOSTNAME="busybear" +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_BPF_SYSCALL=y +CONFIG_SMP=y +CONFIG_MODULES=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_NETLINK_DIAG=y +# CONFIG_WIRELESS is not set +CONFIG_PCI=y +CONFIG_DEVTMPFS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_VIRTIO_BLK=y +CONFIG_NETDEVICES=y +CONFIG_VIRTIO_NET=y +# CONFIG_ETHERNET is not set +# CONFIG_WLAN is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_HVC_RISCV_SBI=y +# CONFIG_HW_RANDOM is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_VIRTIO_MMIO=y +CONFIG_SIFIVE_PLIC=y +CONFIG_RAS=y +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_AUTOFS4_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +# CONFIG_CRYPTO_ECHAINIV is not set +# CONFIG_CRYPTO_HW is not set +CONFIG_PRINTK_TIME=y diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs index efc29163455be..299ec0f0b4c14 100644 --- a/src/tools/remote-test-client/src/main.rs +++ b/src/tools/remote-test-client/src/main.rs @@ -107,13 +107,23 @@ fn start_android_emulator(server: &Path) { Command::new("adb").arg("shell").arg("/data/tmp/testd").spawn().unwrap(); } -fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path) { +fn prepare_rootfs(target: &str, rootfs: &Path, server: &Path, rootfs_img: &Path) { + t!(fs::copy(server, rootfs.join("testd"))); + + match target { + "arm-unknown-linux-gnueabihf" | "aarch64-unknown-linux-gnu" => { + prepare_rootfs_cpio(rootfs, rootfs_img) + } + "riscv64gc-unknown-linux-gnu" => prepare_rootfs_ext4(rootfs, rootfs_img), + _ => panic!("{} is not supported", target), + } +} + +fn prepare_rootfs_cpio(rootfs: &Path, rootfs_img: &Path) { // Generate a new rootfs image now that we've updated the test server // executable. This is the equivalent of: // // find $rootfs -print 0 | cpio --null -o --format=newc > rootfs.img - t!(fs::copy(server, rootfs.join("testd"))); - let rootfs_img = tmpdir.join("rootfs.img"); let mut cmd = Command::new("cpio"); cmd.arg("--null") .arg("-o") @@ -128,6 +138,38 @@ fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path t!(io::copy(&mut child.stdout.take().unwrap(), &mut t!(File::create(&rootfs_img)))); assert!(t!(child.wait()).success()); + fn add_files(w: &mut dyn Write, root: &Path, cur: &Path) { + for entry in t!(cur.read_dir()) { + let entry = t!(entry); + let path = entry.path(); + let to_print = path.strip_prefix(root).unwrap(); + t!(write!(w, "{}\u{0}", to_print.to_str().unwrap())); + if t!(entry.file_type()).is_dir() { + add_files(w, root, &path); + } + } + } +} + +fn prepare_rootfs_ext4(rootfs: &Path, rootfs_img: &Path) { + let mut dd = Command::new("dd"); + dd.arg("if=/dev/zero") + .arg(&format!("of={}", rootfs_img.to_string_lossy())) + .arg("bs=1M") + .arg("count=1024"); + let mut dd_child = t!(dd.spawn()); + assert!(t!(dd_child.wait()).success()); + + let mut mkfs = Command::new("mkfs.ext4"); + mkfs.arg("-d").arg(rootfs).arg(rootfs_img); + let mut mkfs_child = t!(mkfs.spawn()); + assert!(t!(mkfs_child.wait()).success()); +} + +fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path) { + let rootfs_img = &tmpdir.join("rootfs.img"); + prepare_rootfs(target, rootfs, server, rootfs_img); + // Start up the emulator, in the background match target { "arm-unknown-linux-gnueabihf" => { @@ -170,19 +212,30 @@ fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path .arg("virtio-net-device,netdev=net0,mac=00:00:00:00:00:00"); t!(cmd.spawn()); } - _ => panic!("cannot start emulator for: {}" < target), - } - - fn add_files(w: &mut dyn Write, root: &Path, cur: &Path) { - for entry in t!(cur.read_dir()) { - let entry = t!(entry); - let path = entry.path(); - let to_print = path.strip_prefix(root).unwrap(); - t!(write!(w, "{}\u{0}", to_print.to_str().unwrap())); - if t!(entry.file_type()).is_dir() { - add_files(w, root, &path); - } + "riscv64gc-unknown-linux-gnu" => { + let mut cmd = Command::new("qemu-system-riscv64"); + cmd.arg("-nographic") + .arg("-machine") + .arg("virt") + .arg("-m") + .arg("1024") + .arg("-bios") + .arg("none") + .arg("-kernel") + .arg("/tmp/bbl") + .arg("-append") + .arg("quiet console=ttyS0 root=/dev/vda rw") + .arg("-netdev") + .arg("user,id=net0,hostfwd=tcp::12345-:12345") + .arg("-device") + .arg("virtio-net-device,netdev=net0,mac=00:00:00:00:00:00") + .arg("-device") + .arg("virtio-blk-device,drive=hd0") + .arg("-drive") + .arg(&format!("file={},format=raw,id=hd0", &rootfs_img.to_string_lossy())); + t!(cmd.spawn()); } + _ => panic!("cannot start emulator for: {}" < target), } } From 253112d43c46f9c0c6c854dcc2c858741616deed Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Tue, 9 Jun 2020 15:44:31 +0100 Subject: [PATCH 03/16] Mark tests whcih don't work under riscv emulation --- src/libstd/sys/unix/process/process_common.rs | 1 + src/libstd/time.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 2d7267263dedf..6e33cdd3c4826 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -428,6 +428,7 @@ mod tests { // ignored there. #[cfg_attr(target_arch = "arm", ignore)] #[cfg_attr(target_arch = "aarch64", ignore)] + #[cfg_attr(target_arch = "riscv64", ignore)] fn test_process_mask() { unsafe { // Test to make sure that a signal mask does not get inherited. diff --git a/src/libstd/time.rs b/src/libstd/time.rs index c36e78b1d004e..9e4ecc9a80dfb 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -796,11 +796,11 @@ mod tests { // Right now for CI this test is run in an emulator, and apparently the // aarch64 emulator's sense of time is that we're still living in the - // 70s. + // 70s. This is also true for riscv (also qemu) // // Otherwise let's assume that we're all running computers later than // 2000. - if !cfg!(target_arch = "aarch64") { + if !cfg!(target_arch = "aarch64") && !cfg!(target_arch = "riscv64") { assert!(a > thirty_years); } From 086eaf8f69b736a7f4b6b8ee232540993d0c255d Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Wed, 10 Jun 2020 09:01:01 +0100 Subject: [PATCH 04/16] tools: remote-test-client: fix typo Thanks to jfrimmel for pointing this out Co-authored-by: J. Frimmel <31166235+jfrimmel@users.noreply.github.com> --- src/tools/remote-test-client/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs index 299ec0f0b4c14..1fafe109d34e1 100644 --- a/src/tools/remote-test-client/src/main.rs +++ b/src/tools/remote-test-client/src/main.rs @@ -235,7 +235,7 @@ fn start_qemu_emulator(target: &str, rootfs: &Path, server: &Path, tmpdir: &Path .arg(&format!("file={},format=raw,id=hd0", &rootfs_img.to_string_lossy())); t!(cmd.spawn()); } - _ => panic!("cannot start emulator for: {}" < target), + _ => panic!("cannot start emulator for: {}", target), } } From 8bc3122311dd70eabb0020e67e850b2b7904d972 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 15 Jun 2020 15:12:43 +0200 Subject: [PATCH 05/16] ci: allow gating gha on everything but macOS In our GitHub Actions setup macOS is too unreliable to gate on it, but the other builders work fine. This commit splits the macOS builders into a separate job (called auto-fallible), allowing us to gate on the auto job without failing due to macOS spurious failures. --- .github/workflows/ci.yml | 158 ++++++++++++++++++++++++++++------- src/ci/github-actions/ci.yml | 81 ++++++++++-------- 2 files changed, 174 insertions(+), 65 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 355f282921537..7501674f48ffe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -373,35 +373,6 @@ jobs: env: DEPLOY_TOOLSTATES_JSON: toolstates-linux.json os: ubuntu-latest-xl - - name: dist-x86_64-apple - env: - SCRIPT: "./x.py dist" - RUST_CONFIGURE_ARGS: "--target=aarch64-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc" - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.7 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - os: macos-latest - - name: dist-x86_64-apple-alt - env: - SCRIPT: "./x.py dist" - RUST_CONFIGURE_ARGS: "--enable-extended --enable-profiler --set rust.jemalloc" - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.7 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - os: macos-latest - - name: x86_64-apple - env: - SCRIPT: "./x.py test" - RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc" - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.8 - MACOSX_STD_DEPLOYMENT_TARGET: 10.7 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - os: macos-latest - name: x86_64-msvc-1 env: RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler" @@ -589,6 +560,135 @@ jobs: AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" + auto-fallible: + name: auto-fallible + env: + CI_JOB_NAME: "${{ matrix.name }}" + SCCACHE_BUCKET: rust-lang-gha-caches + DEPLOY_BUCKET: rust-lang-gha + TOOLSTATE_REPO: "https://github.com/pietroalbini/rust-toolstate" + TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/pietroalbini/rust-toolstate/issues" + TOOLSTATE_PUBLISH: 1 + CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZOMUQATD5 + ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZH5AYXDVF + CACHE_DOMAIN: ci-caches-gha.rust-lang.org + if: "github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" + strategy: + matrix: + include: + - name: dist-x86_64-apple + env: + SCRIPT: "./x.py dist" + RUST_CONFIGURE_ARGS: "--target=aarch64-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc" + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + DIST_REQUIRE_ALL_TOOLS: 1 + os: macos-latest + - name: dist-x86_64-apple-alt + env: + SCRIPT: "./x.py dist" + RUST_CONFIGURE_ARGS: "--enable-extended --enable-profiler --set rust.jemalloc" + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + os: macos-latest + - name: x86_64-apple + env: + SCRIPT: "./x.py test" + RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc" + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.8 + MACOSX_STD_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + os: macos-latest + timeout-minutes: 600 + runs-on: "${{ matrix.os }}" + steps: + - name: disable git crlf conversion + run: git config --global core.autocrlf false + shell: bash + - name: checkout the source code + uses: actions/checkout@v1 + with: + fetch-depth: 2 + - name: configure GitHub Actions to kill the build when outdated + uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master + with: + github_token: "${{ secrets.github_token }}" + if: "success() && !env.SKIP_JOB && github.ref != 'refs/heads/try'" + - name: add extra environment variables + run: src/ci/scripts/setup-environment.sh + env: + EXTRA_VARIABLES: "${{ toJson(matrix.env) }}" + if: success() && !env.SKIP_JOB + - name: decide whether to skip this job + run: src/ci/scripts/should-skip-this.sh + if: success() && !env.SKIP_JOB + - name: collect CPU statistics + run: src/ci/scripts/collect-cpu-stats.sh + if: success() && !env.SKIP_JOB + - name: show the current environment + run: src/ci/scripts/dump-environment.sh + if: success() && !env.SKIP_JOB + - name: install awscli + run: src/ci/scripts/install-awscli.sh + if: success() && !env.SKIP_JOB + - name: install sccache + run: src/ci/scripts/install-sccache.sh + if: success() && !env.SKIP_JOB + - name: install clang + run: src/ci/scripts/install-clang.sh + if: success() && !env.SKIP_JOB + - name: install WIX + run: src/ci/scripts/install-wix.sh + if: success() && !env.SKIP_JOB + - name: install InnoSetup + run: src/ci/scripts/install-innosetup.sh + if: success() && !env.SKIP_JOB + - name: ensure the build happens on a partition with enough space + run: src/ci/scripts/symlink-build-dir.sh + if: success() && !env.SKIP_JOB + - name: disable git crlf conversion + run: src/ci/scripts/disable-git-crlf-conversion.sh + if: success() && !env.SKIP_JOB + - name: install MSYS2 + run: src/ci/scripts/install-msys2.sh + if: success() && !env.SKIP_JOB + - name: install MinGW + run: src/ci/scripts/install-mingw.sh + if: success() && !env.SKIP_JOB + - name: install ninja + run: src/ci/scripts/install-ninja.sh + if: success() && !env.SKIP_JOB + - name: enable ipv6 on Docker + run: src/ci/scripts/enable-docker-ipv6.sh + if: success() && !env.SKIP_JOB + - name: disable git crlf conversion + run: src/ci/scripts/disable-git-crlf-conversion.sh + if: success() && !env.SKIP_JOB + - name: checkout submodules + run: src/ci/scripts/checkout-submodules.sh + if: success() && !env.SKIP_JOB + - name: ensure line endings are correct + run: src/ci/scripts/verify-line-endings.sh + if: success() && !env.SKIP_JOB + - name: run the build + run: src/ci/scripts/run-build-from-ci.sh + env: + AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}" + AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}" + TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" + if: success() && !env.SKIP_JOB + - name: upload artifacts to S3 + run: src/ci/scripts/upload-artifacts.sh + env: + AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" + AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" + if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" master: name: master runs-on: ubuntu-latest diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 590845b33cda7..6e441f8f5ad50 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -419,42 +419,6 @@ jobs: DEPLOY_TOOLSTATES_JSON: toolstates-linux.json <<: *job-linux-xl - #################### - # macOS Builders # - #################### - - - name: dist-x86_64-apple - env: - SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.7 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - <<: *job-macos-xl - - - name: dist-x86_64-apple-alt - env: - SCRIPT: ./x.py dist - RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.7 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - <<: *job-macos-xl - - - name: x86_64-apple - env: - SCRIPT: ./x.py test - RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.8 - MACOSX_STD_DEPLOYMENT_TARGET: 10.7 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - <<: *job-macos-xl - ###################### # Windows Builders # ###################### @@ -606,6 +570,51 @@ jobs: SCRIPT: python x.py dist <<: *job-windows-xl + auto-fallible: + <<: *base-ci-job + name: auto-fallible + env: + <<: [*shared-ci-variables, *prod-variables] + if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' + strategy: + matrix: + include: + #################### + # macOS Builders # + #################### + + - name: dist-x86_64-apple + env: + SCRIPT: ./x.py dist + RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + DIST_REQUIRE_ALL_TOOLS: 1 + <<: *job-macos-xl + + - name: dist-x86_64-apple-alt + env: + SCRIPT: ./x.py dist + RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + <<: *job-macos-xl + + - name: x86_64-apple + env: + SCRIPT: ./x.py test + RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.8 + MACOSX_STD_DEPLOYMENT_TARGET: 10.7 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + <<: *job-macos-xl + master: name: master runs-on: ubuntu-latest From 2ea386424f1a9065947a5ac246043a6945e90def Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Mon, 15 Jun 2020 18:04:43 +0100 Subject: [PATCH 06/16] Remove use of specialization from librustc_arena --- src/librustc_arena/lib.rs | 91 +++++++++++++++++--------------- src/librustc_ast_lowering/lib.rs | 2 - src/librustc_middle/lib.rs | 1 - 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/src/librustc_arena/lib.rs b/src/librustc_arena/lib.rs index 4a2a0de0e211f..7f154052538ac 100644 --- a/src/librustc_arena/lib.rs +++ b/src/librustc_arena/lib.rs @@ -602,7 +602,7 @@ macro_rules! which_arena_for_type { #[macro_export] macro_rules! declare_arena { - ([], [$($a:tt $name:ident: $ty:ty, $gen_ty:ty;)*], $tcx:lifetime) => { + ([], [$($a:tt $name:ident: $ty:ty, $_gen_ty:ty;)*], $tcx:lifetime) => { #[derive(Default)] pub struct Arena<$tcx> { pub dropless: $crate::DroplessArena, @@ -610,39 +610,56 @@ macro_rules! declare_arena { $($name: $crate::arena_for_type!($a[$ty]),)* } - #[marker] - pub trait ArenaAllocatable<'tcx> {} - - impl<'tcx, T: Copy> ArenaAllocatable<'tcx> for T {} - - unsafe trait ArenaField<'tcx>: Sized + ArenaAllocatable<'tcx> { - /// Returns a specific arena to allocate from. - /// If `None` is returned, the `DropArena` will be used. - fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena>; + pub trait ArenaAllocatable<'tcx, T = Self>: Sized { + fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self; + fn allocate_from_iter<'a>( + arena: &'a Arena<'tcx>, + iter: impl ::std::iter::IntoIterator, + ) -> &'a mut [Self]; } - unsafe impl<'tcx, T: ArenaAllocatable<'tcx>> ArenaField<'tcx> for T { + impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T { #[inline] - default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena> { - panic!() + fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self { + arena.dropless.alloc(self) + } + #[inline] + fn allocate_from_iter<'a>( + arena: &'a Arena<'tcx>, + iter: impl ::std::iter::IntoIterator, + ) -> &'a mut [Self] { + arena.dropless.alloc_from_iter(iter) } - } + } $( - #[allow(unused_lifetimes)] - impl<$tcx> ArenaAllocatable<$tcx> for $ty {} - unsafe impl<$tcx, '_x, '_y, '_z, '_w> ArenaField<$tcx> for $gen_ty where Self: ArenaAllocatable<$tcx> { + impl<$tcx> ArenaAllocatable<$tcx, $ty> for $ty { #[inline] - fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a $crate::TypedArena> { - // SAFETY: We only implement `ArenaAllocatable<$tcx>` for - // `$ty`, so `$ty` and Self are the same type - unsafe { - ::std::mem::transmute::< - Option<&'a $crate::TypedArena<$ty>>, - Option<&'a $crate::TypedArena>, - >( - $crate::which_arena_for_type!($a[&_arena.$name]) - ) + fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self { + if !::std::mem::needs_drop::() { + return arena.dropless.alloc(self); + } + match $crate::which_arena_for_type!($a[&arena.$name]) { + ::std::option::Option::<&$crate::TypedArena>::Some(ty_arena) => { + ty_arena.alloc(self) + } + ::std::option::Option::None => unsafe { arena.drop.alloc(self) }, + } + } + + #[inline] + fn allocate_from_iter<'a>( + arena: &'a Arena<$tcx>, + iter: impl ::std::iter::IntoIterator, + ) -> &'a mut [Self] { + if !::std::mem::needs_drop::() { + return arena.dropless.alloc_from_iter(iter); + } + match $crate::which_arena_for_type!($a[&arena.$name]) { + ::std::option::Option::<&$crate::TypedArena>::Some(ty_arena) => { + ty_arena.alloc_from_iter(iter) + } + ::std::option::Option::None => unsafe { arena.drop.alloc_from_iter(iter) }, } } } @@ -650,14 +667,8 @@ macro_rules! declare_arena { impl<'tcx> Arena<'tcx> { #[inline] - pub fn alloc>(&self, value: T) -> &mut T { - if !::std::mem::needs_drop::() { - return self.dropless.alloc(value); - } - match >::arena(self) { - ::std::option::Option::Some(arena) => arena.alloc(value), - ::std::option::Option::None => unsafe { self.drop.alloc(value) }, - } + pub fn alloc, U>(&self, value: T) -> &mut T { + value.allocate_on(self) } #[inline] @@ -668,17 +679,11 @@ macro_rules! declare_arena { self.dropless.alloc_slice(value) } - pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx>>( + pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, U>, U>( &'a self, iter: impl ::std::iter::IntoIterator, ) -> &'a mut [T] { - if !::std::mem::needs_drop::() { - return self.dropless.alloc_from_iter(iter); - } - match >::arena(self) { - ::std::option::Option::Some(arena) => arena.alloc_from_iter(iter), - ::std::option::Option::None => unsafe { self.drop.alloc_from_iter(iter) }, - } + T::allocate_from_iter(self, iter) } } } diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index a722a88a7a102..af1e33a049bfb 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -32,8 +32,6 @@ #![feature(array_value_iter)] #![feature(crate_visibility_modifier)] -#![feature(marker_trait_attr)] -#![feature(min_specialization)] #![feature(or_patterns)] #![recursion_limit = "256"] diff --git a/src/librustc_middle/lib.rs b/src/librustc_middle/lib.rs index 62c92e988ba60..2e27ab514d80b 100644 --- a/src/librustc_middle/lib.rs +++ b/src/librustc_middle/lib.rs @@ -36,7 +36,6 @@ #![feature(drain_filter)] #![feature(never_type)] #![feature(exhaustive_patterns)] -#![feature(marker_trait_attr)] #![feature(extern_types)] #![feature(nll)] #![feature(option_expect_none)] From 6f738a0cfc70e1c2cb48b2d2a2f53e85747dc767 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 16 Jun 2020 08:52:00 -0700 Subject: [PATCH 07/16] Update bootstrap to rustc 1.45.0-beta.2 (1dc0f6d8e 2020-06-15) --- src/stage0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stage0.txt b/src/stage0.txt index 5e840b9db1994..769ec669bdc8d 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.(x+1).0` for Cargo where they were released on `date`. -date: 2020-06-03 +date: 2020-06-16 rustc: beta cargo: beta From 8f5ff7b379ea61ee5da5200c92ea603eb955c506 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 16 Jun 2020 09:22:27 -0700 Subject: [PATCH 08/16] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 79c769c3d7b4c..089cbb80b73ba 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 79c769c3d7b4c2cf6a93781575b7f592ef974255 +Subproject commit 089cbb80b73ba242efdcf5430e89f63fa3b5328d From 83e6c0e98657d8df3dd4f45fa22baadcac986402 Mon Sep 17 00:00:00 2001 From: Andrew Paverd Date: Tue, 16 Jun 2020 17:44:03 +0100 Subject: [PATCH 09/16] Update CFGuard syntax --- src/bootstrap/builder.rs | 4 +-- .../src/compiler-flags/control-flow-guard.md | 10 +++---- src/librustc_interface/tests.rs | 2 +- src/librustc_session/config.rs | 2 +- src/librustc_session/options.rs | 29 ++++++++++++++----- src/test/codegen/cfguard_checks.rs | 2 +- src/test/codegen/cfguard_disabled.rs | 2 +- src/test/codegen/cfguard_nochecks.rs | 2 +- 8 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index ea5300bdfc04c..087b0da74e5e1 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1176,7 +1176,7 @@ impl<'a> Builder<'a> { ); } - // If Control Flow Guard is enabled, pass the `control_flow_guard=checks` flag to rustc + // If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc // when compiling the standard library, since this might be linked into the final outputs // produced by rustc. Since this mitigation is only available on Windows, only enable it // for the standard library in case the compiler is run on a non-Windows platform. @@ -1187,7 +1187,7 @@ impl<'a> Builder<'a> { && self.config.control_flow_guard && compiler.stage >= 1 { - rustflags.arg("-Zcontrol_flow_guard=checks"); + rustflags.arg("-Zcontrol-flow-guard"); } // For `cargo doc` invocations, make rustdoc print the Rust version into the docs diff --git a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md index 48dea213e8cee..4115825e92083 100644 --- a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md +++ b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md @@ -1,10 +1,10 @@ -# `control_flow_guard` +# `control-flow-guard` The tracking issue for this feature is: [#68793](https://github.com/rust-lang/rust/issues/68793). ------------------------ -The rustc flag `-Z control_flow_guard=checks` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature. +The rustc flag `-Z control-flow-guard` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature. CFG is an exploit mitigation designed to enforce control-flow integrity for software running on supported Windows platforms (Windows 8.1 onwards). Specifically, CFG uses runtime checks to validate the target address of every indirect call/jump before allowing the call to complete. @@ -29,7 +29,7 @@ The CFG checks and metadata can potentially increase binary size and runtime ove ## Testing Control Flow Guard -The rustc flag `-Z control_flow_guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement. +The rustc flag `-Z control-flow-guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement. ## Control Flow Guard in libraries @@ -44,14 +44,14 @@ For example: ```cmd rustup toolchain install --force nightly rustup component add rust-src -SET RUSTFLAGS=-Z control_flow_guard=checks +SET RUSTFLAGS=-Z control-flow-guard cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc ``` ```PowerShell rustup toolchain install --force nightly rustup component add rust-src -$Env:RUSTFLAGS = "-Z control_flow_guard=checks" +$Env:RUSTFLAGS = "-Z control-flow-guard" cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc ``` diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs index 87647f3b0b017..bbe2e8da12e7c 100644 --- a/src/librustc_interface/tests.rs +++ b/src/librustc_interface/tests.rs @@ -463,7 +463,6 @@ fn test_debugging_options_tracking_hash() { untracked!(ast_json_noexpand, true); untracked!(borrowck, String::from("other")); untracked!(borrowck_stats, true); - untracked!(control_flow_guard, CFGuard::Checks); untracked!(deduplicate_diagnostics, true); untracked!(dep_tasks, true); untracked!(dont_buffer_diagnostics, true); @@ -537,6 +536,7 @@ fn test_debugging_options_tracking_hash() { tracked!(binary_dep_depinfo, true); tracked!(chalk, true); tracked!(codegen_backend, Some("abc".to_string())); + tracked!(control_flow_guard, CFGuard::Checks); tracked!(crate_attr, vec!["abc".to_string()]); tracked!(debug_macros, true); tracked!(dep_info_omit_d_target, true); diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 411a6eecbba15..562f71e8e9287 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -82,7 +82,7 @@ pub enum Strip { Symbols, } -/// The different settings that the `-Z control_flow_guard` flag can have. +/// The different settings that the `-Z control-flow-guard` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum CFGuard { /// Do not emit Control Flow Guard metadata or checks. diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index d22c6ec9d7d01..e822e79bf4fa2 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -251,7 +251,8 @@ macro_rules! options { pub const parse_sanitizer: &str = "one of: `address`, `leak`, `memory` or `thread`"; pub const parse_sanitizer_list: &str = "comma separated list of sanitizers"; pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; - pub const parse_cfguard: &str = "either `disabled`, `nochecks`, or `checks`"; + pub const parse_cfguard: &str = + "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of(); pub const parse_optimization_fuel: &str = "crate=integer"; @@ -505,12 +506,24 @@ macro_rules! options { } fn parse_cfguard(slot: &mut CFGuard, v: Option<&str>) -> bool { - match v { - Some("disabled") => *slot = CFGuard::Disabled, - Some("nochecks") => *slot = CFGuard::NoChecks, - Some("checks") => *slot = CFGuard::Checks, - _ => return false, + if v.is_some() { + let mut bool_arg = None; + if parse_opt_bool(&mut bool_arg, v) { + *slot = if bool_arg.unwrap() { + CFGuard::Checks + } else { + CFGuard::Disabled + }; + return true + } } + + *slot = match v { + None => CFGuard::Checks, + Some("checks") => CFGuard::Checks, + Some("nochecks") => CFGuard::NoChecks, + Some(_) => return false, + }; true } @@ -806,8 +819,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "enable the experimental Chalk-based trait solving engine"), codegen_backend: Option = (None, parse_opt_string, [TRACKED], "the backend to use"), - control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [UNTRACKED], - "use Windows Control Flow Guard (`disabled`, `nochecks` or `checks`)"), + control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED], + "use Windows Control Flow Guard (default: no)"), crate_attr: Vec = (Vec::new(), parse_string_push, [TRACKED], "inject the given attribute in the crate"), debug_macros: bool = (false, parse_bool, [TRACKED], diff --git a/src/test/codegen/cfguard_checks.rs b/src/test/codegen/cfguard_checks.rs index 40a7353eac045..96f9158f9d394 100644 --- a/src/test/codegen/cfguard_checks.rs +++ b/src/test/codegen/cfguard_checks.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z control_flow_guard=checks +// compile-flags: -Z control-flow-guard=checks #![crate_type = "lib"] diff --git a/src/test/codegen/cfguard_disabled.rs b/src/test/codegen/cfguard_disabled.rs index d1747931e15c8..1325ffc0f2595 100644 --- a/src/test/codegen/cfguard_disabled.rs +++ b/src/test/codegen/cfguard_disabled.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z control_flow_guard=disabled +// compile-flags: -Z control-flow-guard=no #![crate_type = "lib"] diff --git a/src/test/codegen/cfguard_nochecks.rs b/src/test/codegen/cfguard_nochecks.rs index c5d7afbae257b..ae1de4c4d26d5 100644 --- a/src/test/codegen/cfguard_nochecks.rs +++ b/src/test/codegen/cfguard_nochecks.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z control_flow_guard=nochecks +// compile-flags: -Z control-flow-guard=nochecks #![crate_type = "lib"] From 1b92d592b5c7f8a3d399e5b9005f4b316b316ef1 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Tue, 16 Jun 2020 19:29:53 +0100 Subject: [PATCH 10/16] Explain unused macro param --- src/librustc_arena/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_arena/lib.rs b/src/librustc_arena/lib.rs index 7f154052538ac..a21d30bf817e3 100644 --- a/src/librustc_arena/lib.rs +++ b/src/librustc_arena/lib.rs @@ -602,6 +602,10 @@ macro_rules! which_arena_for_type { #[macro_export] macro_rules! declare_arena { + // This macro has to take the same input as + // `impl_arena_allocatable_decoders` which requires a second version of + // each type. We ignore that type until we can fix + // `impl_arena_allocatable_decoders`. ([], [$($a:tt $name:ident: $ty:ty, $_gen_ty:ty;)*], $tcx:lifetime) => { #[derive(Default)] pub struct Arena<$tcx> { From afde8601d6ba5a8dabe87ffe69e96060fb330007 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 17 Jun 2020 17:17:25 +0200 Subject: [PATCH 11/16] ci: disable alt build during try builds The build is not actually needed often, and it can be added back on a case-by-case basis if a specific PR needs access to it. --- .github/workflows/ci.yml | 4 ---- src/ci/azure-pipelines/try.yml | 2 -- src/ci/github-actions/ci.yml | 5 ----- 3 files changed, 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf3c22744f165..5f9311635f6bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,10 +152,6 @@ jobs: - name: dist-x86_64-linux os: ubuntu-latest-xl env: {} - - name: dist-x86_64-linux-alt - env: - IMAGE: dist-x86_64-linux - os: ubuntu-latest-xl timeout-minutes: 600 runs-on: "${{ matrix.os }}" steps: diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml index 38a0685e0f75a..818306a009229 100644 --- a/src/ci/azure-pipelines/try.yml +++ b/src/ci/azure-pipelines/try.yml @@ -26,8 +26,6 @@ jobs: strategy: matrix: dist-x86_64-linux: {} - dist-x86_64-linux-alt: - IMAGE: dist-x86_64-linux # The macOS and Windows builds here are currently disabled due to them not being # overly necessary on `try` builds. We also don't actually have anything that diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index a052d0879a3db..daa2d55c04399 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -281,11 +281,6 @@ jobs: - name: dist-x86_64-linux <<: *job-linux-xl - - name: dist-x86_64-linux-alt - env: - IMAGE: dist-x86_64-linux - <<: *job-linux-xl - auto: <<: *base-ci-job name: auto From daedb7920f48941bd8ffa1b1463b417b1641c823 Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Wed, 17 Jun 2020 18:07:12 +0200 Subject: [PATCH 12/16] Prevent attacker from manipulating FPU tag word used in SGX enclave Insufficient sanitization of the x87 FPU tag word in the trusted enclave runtime allowed unprivileged adversaries in the containing host application to induce incoherent or unexpected results for ABI-compliant compiled enclave application code that uses the x87 FPU. Vulnerability was disclosed to us by Fritz Alder, Jo Van Bulck, David Oswald and Frank Piessens --- src/libstd/sys/sgx/abi/entry.S | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index 2badfc973c972..0c3afa77a60f3 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -177,6 +177,13 @@ sgx_entry: jz .Lskip_debug_init mov %r10,%gs:tcsls_debug_panic_buf_ptr .Lskip_debug_init: +/* reset cpu state */ + mov %rdx, %r10 + mov $-1, %rax + mov $-1, %rdx + xrstor .Lxsave_clear(%rip) + mov %r10, %rdx + /* check if returning from usercall */ mov %gs:tcsls_last_rsp,%r11 test %r11,%r11 From c9c434dd8bcd84a30edd070e91f0d6c027333c84 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Fri, 19 Jun 2020 00:15:11 -0400 Subject: [PATCH 13/16] Converted all platform-specific stdin/stdout/stderr implementations to io traits --- src/libstd/sys/hermit/stdio.rs | 37 +++++++++---------- src/libstd/sys/wasi/stdio.rs | 66 +++++++++++++++++----------------- 2 files changed, 49 insertions(+), 54 deletions(-) diff --git a/src/libstd/sys/hermit/stdio.rs b/src/libstd/sys/hermit/stdio.rs index 208265de465ad..59f9c3644e848 100644 --- a/src/libstd/sys/hermit/stdio.rs +++ b/src/libstd/sys/hermit/stdio.rs @@ -10,19 +10,21 @@ impl Stdin { pub fn new() -> io::Result { Ok(Stdin) } +} - pub fn read(&self, data: &mut [u8]) -> io::Result { +impl io::Read for Stdin { + fn read(&mut self, data: &mut [u8]) -> io::Result { self.read_vectored(&mut [IoSliceMut::new(data)]) } - pub fn read_vectored(&self, _data: &mut [IoSliceMut<'_>]) -> io::Result { + fn read_vectored(&self, _data: &mut [IoSliceMut<'_>]) -> io::Result { //ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) }) // .read(data) Ok(0) } #[inline] - pub fn is_read_vectored(&self) -> bool { + fn is_read_vectored(&self) -> bool { true } } @@ -31,8 +33,10 @@ impl Stdout { pub fn new() -> io::Result { Ok(Stdout) } +} - pub fn write(&self, data: &[u8]) -> io::Result { +impl io::Write for Stdout { + fn write(&mut self, data: &[u8]) -> io::Result { let len; unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) } @@ -44,7 +48,7 @@ impl Stdout { } } - pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { + fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { let len; unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) } @@ -57,11 +61,11 @@ impl Stdout { } #[inline] - pub fn is_write_vectored(&self) -> bool { + fn is_write_vectored(&self) -> bool { true } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } @@ -70,8 +74,10 @@ impl Stderr { pub fn new() -> io::Result { Ok(Stderr) } +} - pub fn write(&self, data: &[u8]) -> io::Result { +impl io::Write for Stderr { + fn write(&mut self, data: &[u8]) -> io::Result { let len; unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) } @@ -83,7 +89,7 @@ impl Stderr { } } - pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { + fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { let len; unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) } @@ -96,21 +102,12 @@ impl Stderr { } #[inline] - pub fn is_write_vectored(&self) -> bool { + fn is_write_vectored(&self) -> bool { true } - pub fn flush(&self) -> io::Result<()> { - Ok(()) - } -} - -impl io::Write for Stderr { - fn write(&mut self, data: &[u8]) -> io::Result { - (&*self).write(data) - } fn flush(&mut self) -> io::Result<()> { - (&*self).flush() + Ok(()) } } diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs index 9f9e35566ecf5..78e3911dc4efe 100644 --- a/src/libstd/sys/wasi/stdio.rs +++ b/src/libstd/sys/wasi/stdio.rs @@ -11,22 +11,25 @@ impl Stdin { Ok(Stdin) } - pub fn read(&self, data: &mut [u8]) -> io::Result { + #[inline] + pub fn as_raw_fd(&self) -> u32 { + 0 + } +} + +impl io::Read for Stdin { + fn read(&mut self, data: &mut [u8]) -> io::Result { self.read_vectored(&mut [IoSliceMut::new(data)]) } - pub fn read_vectored(&self, data: &mut [IoSliceMut<'_>]) -> io::Result { + fn read_vectored(&mut self, data: &mut [IoSliceMut<'_>]) -> io::Result { ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).read(data) } #[inline] - pub fn is_read_vectored(&self) -> bool { + fn is_read_vectored(&self) -> bool { true } - - pub fn as_raw_fd(&self) -> u32 { - 0 - } } impl Stdout { @@ -34,26 +37,28 @@ impl Stdout { Ok(Stdout) } - pub fn write(&self, data: &[u8]) -> io::Result { + #[inline] + pub fn as_raw_fd(&self) -> u32 { + 1 + } +} + +impl io::Write for Stdout { + fn write(&mut self, data: &[u8]) -> io::Result { self.write_vectored(&[IoSlice::new(data)]) } - pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { + fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data) } #[inline] - pub fn is_write_vectored(&self) -> bool { + fn is_write_vectored(&self) -> bool { true } - - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } - - pub fn as_raw_fd(&self) -> u32 { - 1 - } } impl Stderr { @@ -61,23 +66,7 @@ impl Stderr { Ok(Stderr) } - pub fn write(&self, data: &[u8]) -> io::Result { - self.write_vectored(&[IoSlice::new(data)]) - } - - pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { - ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data) - } - #[inline] - pub fn is_write_vectored(&self) -> bool { - true - } - - pub fn flush(&self) -> io::Result<()> { - Ok(()) - } - pub fn as_raw_fd(&self) -> u32 { 2 } @@ -85,11 +74,20 @@ impl Stderr { impl io::Write for Stderr { fn write(&mut self, data: &[u8]) -> io::Result { - (&*self).write(data) + self.write_vectored(&[IoSlice::new(data)]) + } + + fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { + ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true } fn flush(&mut self) -> io::Result<()> { - (&*self).flush() + Ok(()) } } From e93362b9746a42638a28f382f41cdb5e2f01f8f6 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Fri, 19 Jun 2020 11:32:36 -0400 Subject: [PATCH 14/16] Fixed missing `mut` --- src/libstd/sys/hermit/stdio.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/hermit/stdio.rs b/src/libstd/sys/hermit/stdio.rs index 59f9c3644e848..dfa154f128bd7 100644 --- a/src/libstd/sys/hermit/stdio.rs +++ b/src/libstd/sys/hermit/stdio.rs @@ -17,7 +17,7 @@ impl io::Read for Stdin { self.read_vectored(&mut [IoSliceMut::new(data)]) } - fn read_vectored(&self, _data: &mut [IoSliceMut<'_>]) -> io::Result { + fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result { //ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) }) // .read(data) Ok(0) From 0094f44a0b54d6ac92f3feaa939d6a3d48cb7475 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Fri, 19 Jun 2020 11:42:58 -0400 Subject: [PATCH 15/16] Remove old commented code --- src/libstd/sys/hermit/stdio.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libstd/sys/hermit/stdio.rs b/src/libstd/sys/hermit/stdio.rs index dfa154f128bd7..f3654ee38716c 100644 --- a/src/libstd/sys/hermit/stdio.rs +++ b/src/libstd/sys/hermit/stdio.rs @@ -18,8 +18,6 @@ impl io::Read for Stdin { } fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result { - //ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) }) - // .read(data) Ok(0) } From 33b304c5e0a620350e0eba0ceda2aab23f3b4e6f Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Fri, 19 Jun 2020 14:20:35 +0200 Subject: [PATCH 16/16] Using xsave restore to restore complete FPU state --- src/libstd/sys/sgx/abi/entry.S | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index 0c3afa77a60f3..fc6ce5770338e 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -26,18 +26,10 @@ IMAGE_BASE: .Lxsave_clear: .org .+24 .Lxsave_mxcsr: - .int 0 + .short 0x1f80 /* We can store a bunch of data in the gap between MXCSR and the XSAVE header */ -/* MXCSR initialization value for ABI */ -.Lmxcsr_init: - .int 0x1f80 - -/* x87 FPU control word initialization value for ABI */ -.Lfpucw_init: - .int 0x037f - /* The following symbols point at read-only data that will be filled in by the */ /* post-linker. */ @@ -188,9 +180,6 @@ sgx_entry: mov %gs:tcsls_last_rsp,%r11 test %r11,%r11 jnz .Lusercall_ret -/* reset user state */ - ldmxcsr .Lmxcsr_init(%rip) - fldcw .Lfpucw_init(%rip) /* setup stack */ mov %gs:tcsls_tos,%rsp /* initially, RSP is not set to the correct value */ /* here. This is fixed below under "adjust stack". */