Skip to content

Commit

Permalink
Auto merge of #57130 - VardhanThigle:Vardhan/x86_64-fortanix-unknown-…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
bors committed Jan 15, 2019
2 parents aea9f0a + 99fbd1b commit 33e6df4
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 20 deletions.
53 changes: 33 additions & 20 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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<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));
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/ci/docker/dist-various-2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions src/ci/docker/dist-various-2/shared.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
10 changes: 10 additions & 0 deletions src/libstd/sys/sgx/abi/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
8 changes: 8 additions & 0 deletions src/libstd/sys/sgx/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ impl Instant {
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 {
Expand Down
1 change: 1 addition & 0 deletions src/libstd/sys/sgx/waitqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit 33e6df4

Please sign in to comment.