diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8bc7c5838edda..b581271663e7e 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -78,11 +78,8 @@ impl Step for Std { builder.info(&format!("Uplifting stage1 std ({} -> {})", from.host, target)); // Even if we're not building std this stage, the new sysroot must - // still contain the musl startup objects. - if target.contains("musl") { - let libdir = builder.sysroot_libdir(compiler, target); - copy_musl_third_party_objects(builder, target, &libdir); - } + // still contain the third party objects needed by various targets. + copy_third_party_objects(builder, &compiler, target); builder.ensure(StdLink { compiler: from, @@ -92,10 +89,7 @@ impl Step for Std { return; } - if target.contains("musl") { - let libdir = builder.sysroot_libdir(compiler, target); - copy_musl_third_party_objects(builder, target, &libdir); - } + copy_third_party_objects(builder, &compiler, target); let mut cargo = builder.cargo(compiler, Mode::Std, target, "build"); std_cargo(builder, &compiler, target, &mut cargo); @@ -116,17 +110,36 @@ impl Step for Std { } } -/// Copies the crt(1,i,n).o startup objects -/// -/// Since musl supports fully static linking, we can cross link for it even -/// with a glibc-targeting toolchain, given we have the appropriate startup -/// files. As those shipped with glibc won't work, copy the ones provided by -/// musl so we have them on linux-gnu hosts. -fn copy_musl_third_party_objects(builder: &Builder, - target: Interned, - into: &Path) { - for &obj in &["crt1.o", "crti.o", "crtn.o"] { - builder.copy(&builder.musl_root(target).unwrap().join("lib").join(obj), &into.join(obj)); +/// Copies third pary objects needed by various targets. +fn copy_third_party_objects(builder: &Builder, compiler: &Compiler, target: Interned) { + let libdir = builder.sysroot_libdir(*compiler, target); + + // Copies the crt(1,i,n).o startup objects + // + // Since musl supports fully static linking, we can cross link for it even + // with a glibc-targeting toolchain, given we have the appropriate startup + // files. As those shipped with glibc won't work, copy the ones provided by + // musl so we have them on linux-gnu hosts. + if target.contains("musl") { + for &obj in &["crt1.o", "crti.o", "crtn.o"] { + builder.copy( + &builder.musl_root(target).unwrap().join("lib").join(obj), + &libdir.join(obj), + ); + } + } + + // Copies libunwind.a compiled to be linked wit x86_64-fortanix-unknown-sgx. + // + // This target needs to be linked to Fortanix's port of llvm's libunwind. + // libunwind requires support for rwlock and printing to stderr, + // which is provided by std for this target. + if target == "x86_64-fortanix-unknown-sgx" { + let src_path_env = "X86_FORTANIX_SGX_LIBS"; + let obj = "libunwind.a"; + let src = env::var(src_path_env).expect(&format!("{} not found in env", src_path_env)); + let src = Path::new(&src).join(obj); + builder.copy(&src, &libdir.join(obj)); } } diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index 944c2a51b8d1f..906255533ad29 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -29,6 +29,10 @@ RUN /tmp/build-fuchsia-toolchain.sh COPY dist-various-2/build-solaris-toolchain.sh /tmp/ RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc +COPY dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/ +# We pass the commit id of the port of LLVM's libunwind to the build script. +# Any update to the commit id here, should cause the container image to be re-built from this point on. +RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "bbe23902411be88d7388f381becefadd6e3ef819" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh @@ -65,6 +69,9 @@ ENV TARGETS=$TARGETS,wasm32-unknown-unknown ENV TARGETS=$TARGETS,x86_64-sun-solaris ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32 ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi +ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx + +ENV X86_FORTANIX_SGX_LIBS="/x86_64-fortanix-unknown-sgx/lib/" ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh b/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh new file mode 100755 index 0000000000000..76921316df2cc --- /dev/null +++ b/src/ci/docker/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +set -eu +source shared.sh + +if [ -z "$1" ]; then + echo "Usage: ${0} " + exit -1 +fi + +target="x86_64-fortanix-unknown-sgx" +url="https://github.com/fortanix/llvm-project/archive/${1}.tar.gz" +repo_name="llvm-project" + +install_prereq() +{ + apt-get update + apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + cmake \ + git +} + +# Clone Fortanix's port of llvm-project to build libunwind that would link with this target. +# The below method to download a single commit from llvm-project is based on fetch_submodule +# from init_repo.sh +fetch_llvm_commit() +{ + cached="download-${repo_name}.tar.gz" + curl -f -sSL -o ${cached} ${url} + tar -xvzf ${cached} + mkdir "./${repo_name}" && tar -xf ${cached} -C ${repo_name} --strip-components 1 +} + +build_unwind() +{ + dir_name="${target}_temp" + rm -rf "./${dir_name}" + mkdir -p ${dir_name} + cd ${dir_name} + + retry fetch_llvm_commit + cd "${repo_name}/libunwind" + + # Build libunwind + mkdir -p build + cd build + cmake -DCMAKE_BUILD_TYPE="RELEASE" -DRUST_SGX=1 -G "Unix Makefiles" -DLLVM_PATH=../../llvm/ ../ + make unwind_static + install -D "lib/libunwind.a" "/${target}/lib/libunwind.a" + rm -rf ${dir_name} +} + +set -x +hide_output install_prereq +hide_output build_unwind diff --git a/src/ci/docker/dist-various-2/shared.sh b/src/ci/docker/dist-various-2/shared.sh index 2b5eccb3189f3..fb917b0510e40 100644 --- a/src/ci/docker/dist-various-2/shared.sh +++ b/src/ci/docker/dist-various-2/shared.sh @@ -13,3 +13,21 @@ exit 1 kill $PING_LOOP_PID set -x } + +function retry { + echo "Attempting with retry:" "$@" + local n=1 + local max=5 + while true; do + "$@" && break || { + if [[ $n -lt $max ]]; then + sleep $n # don't retry immediately + ((n++)) + echo "Command failed. Attempt $n/$max:" + else + echo "The command has failed after $n attempts." + return 1 + fi + } + done +} diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index 8dad6ee976ff8..ac7f95d4eae80 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -4,6 +4,16 @@ .global IMAGE_BASE IMAGE_BASE: +.section ".note.x86_64-fortanix-unknown-sgx", "", @note + .align 4 + .long 1f - 0f /* name length (not including padding) */ + .long 3f - 2f /* desc length (not including padding) */ + .long 1 /* type = NT_VERSION */ +0: .asciz "toolchain-version" /* name */ +1: .align 4 +2: .long 0 /* desc - toolchain version number, 32-bit LE */ +3: .align 4 + .section .rodata /* The XSAVE area needs to be a large chunk of readable memory, but since we are */ /* going to restore everything to its initial state (XSTATE_BV=0), only certain */ diff --git a/src/libstd/sys/sgx/time.rs b/src/libstd/sys/sgx/time.rs index 10fe72d5f6869..407fe72b0e623 100644 --- a/src/libstd/sys/sgx/time.rs +++ b/src/libstd/sys/sgx/time.rs @@ -25,6 +25,14 @@ impl Instant { pub fn checked_sub_duration(&self, other: &Duration) -> Option { Some(Instant(self.0.checked_sub(*other)?)) } + + pub fn actually_monotonic() -> bool { + false + } + + pub const fn zero() -> Instant { + Instant(Duration::from_secs(0)) + } } impl SystemTime { diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs index a47382087782d..51c00a1433e76 100644 --- a/src/libstd/sys/sgx/waitqueue.rs +++ b/src/libstd/sys/sgx/waitqueue.rs @@ -456,6 +456,7 @@ mod spin_mutex { } } + /// Lock the Mutex or return false. pub macro try_lock_or_false { ($e:expr) => { if let Some(v) = $e.try_lock() {