Auto merge of #57130 - VardhanThigle:Vardhan/x86_64-fortanix-unknown-sgx-tier2_support, r=alexcrichton
Upgrade x86_64-fortanix-unknown-sgx platform support to tier 2
## Overview
1. This PR upgrades x86_64-fortanix-unknown-sgx platform support to tier 2 (std only) by setting up build automation for this target.
1. For supporting unwinding, this target needs to link to a port of LLVM's libunwind (more details could be found in #56979), which will be distributed along with the Rust binaries (similar to the extra musl objects)
### Building and copying libunwind:
We have added a new build script (`build-x86_64-fortanix-unknown-sgx-toolchain.sh`) that will run while the container is built. This will build `libunwind.a` from git source.
While the container is built, the persistent volumes where obj/ gets created aren't yet mapped. As a workaround, we copy the built `libunwind.a` to `obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-fortanix-unknown-sgx/lib/` after x.py runs.
If any reviewer knows of a better solution, please do tell.
r? @Mark-Simulacrum
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 8bc7c58..b581271 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -78,11 +78,8 @@
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 @@
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 @@
}
}
-/// 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<String>,
- 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<String>) {
+ 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 944c2a5..9062555 100644
--- a/src/ci/docker/dist-various-2/Dockerfile
+++ b/src/ci/docker/dist-various-2/Dockerfile
@@ -29,6 +29,10 @@
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,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 0000000..7692131
--- /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} <commit_id>"
+ 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 2b5eccb..fb917b0 100644
--- a/src/ci/docker/dist-various-2/shared.sh
+++ b/src/ci/docker/dist-various-2/shared.sh
@@ -13,3 +13,21 @@
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 8dad6ee..ac7f95d 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 10fe72d..407fe72 100644
--- a/src/libstd/sys/sgx/time.rs
+++ b/src/libstd/sys/sgx/time.rs
@@ -25,6 +25,14 @@
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
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 a473820..51c00a1 100644
--- a/src/libstd/sys/sgx/waitqueue.rs
+++ b/src/libstd/sys/sgx/waitqueue.rs
@@ -456,6 +456,7 @@
}
}
+ /// Lock the Mutex or return false.
pub macro try_lock_or_false {
($e:expr) => {
if let Some(v) = $e.try_lock() {