Skip to content
This repository has been archived by the owner on Oct 26, 2021. It is now read-only.

Add wasmldr #512

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: test
args: ${{ matrix.profile.flag }} --no-default-features --features=backend-${{ matrix.backend.name }}
args: ${{ matrix.profile.flag }} --no-default-features --features=backend-${{ matrix.backend.name }} --features=wasmldr
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -50,6 +50,7 @@ jobs:
crate:
- shim-sgx
- shim-sev
- wasmldr
profile:
- name: debug
- name: release
Expand Down
25 changes: 25 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ is-it-maintained-issue-resolution = { repository = "enarx/enarx-keepldr" }
is-it-maintained-open-issues = { repository = "enarx/enarx-keepldr" }

[features]
default = ["backend-kvm", "backend-sgx"]
default = ["backend-kvm", "backend-sgx", "wasmldr"]

backend-kvm = ["x86_64", "kvm-bindings", "kvm-ioctls"]
backend-sgx = ["x86_64", "sgx"]
wasmldr = ["wat"]

[dependencies]
sgx = { git = "https://github.com/enarx/sgx", rev = "57df3753a0ea1777963dbf3023452993df2edb8c", features = ["openssl"], optional = true }
Expand Down Expand Up @@ -54,6 +55,7 @@ vdso = "0.1"

[build-dependencies]
cc = "1.0"
wat = { version = "1.0", optional = true }
walkdir = "2"
protobuf-codegen-pure = "2.25"
sallyport = { git = "https://github.com/enarx/sallyport", rev = "a567a22665c7e5ba88a8c4acd64ab43ee32b4681", features = [ "asm" ] }
Expand Down
230 changes: 123 additions & 107 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,111 @@ fn build_cc_tests(in_path: &Path, out_path: &Path) {
}
}

#[cfg(feature = "wasmldr")]
fn build_wasm_tests(in_path: &Path, out_path: &Path) {
for wat in find_files_with_extensions(&["wat"], &in_path) {
let wasm = out_path
.join(wat.file_stem().unwrap())
.with_extension("wasm");
let bin = wat::parse_file(&wat).unwrap_or_else(|_| panic!("failed to compile {:?}", &wat));
std::fs::write(&wasm, &bin).unwrap_or_else(|_| panic!("failed to write {:?}", &wasm));
println!("cargo:rerun-if-changed={}", &wat.display());
}
}

// Build a binary named `bin_name` from the crate located at `in_dir`,
// targeting `target_name`, then strip the resulting binary and place it
// at `out_dir`/bin/`bin_name`.
fn cargo_build_bin(
in_dir: &Path,
out_dir: &Path,
target_name: &str,
bin_name: &str,
) -> std::io::Result<()> {
let profile: &[&str] = match std::env::var("PROFILE").unwrap().as_str() {
"release" => &["--release"],
_ => &[],
};

let filtered_env: HashMap<String, String> = std::env::vars()
.filter(|&(ref k, _)| {
k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH" || k == "RUSTUP_HOME"
})
.collect();

let path = in_dir.as_os_str().to_str().unwrap();

println!("cargo:rerun-if-changed={}/Cargo.tml", path);
println!("cargo:rerun-if-changed={}/Cargo.toml", path);
println!("cargo:rerun-if-changed={}/Cargo.lock", path);
println!("cargo:rerun-if-changed={}/layout.ld", path);
println!("cargo:rerun-if-changed={}/.cargo/config", path);

rerun_src(&path);

let target_dir = out_dir.join(path);

let stdout: Stdio = OpenOptions::new()
.write(true)
.open("/dev/tty")
.map(Stdio::from)
.unwrap_or_else(|_| Stdio::inherit());

let stderr: Stdio = OpenOptions::new()
.write(true)
.open("/dev/tty")
.map(Stdio::from)
.unwrap_or_else(|_| Stdio::inherit());

let status = Command::new("cargo")
.current_dir(&path)
.env_clear()
.envs(&filtered_env)
.stdout(stdout)
.stderr(stderr)
.arg("+nightly-2021-09-30") // See rust-lang/rust#89432
.arg("build")
.args(profile)
.arg("--target-dir")
.arg(&target_dir)
.arg("--target")
.arg(target_name)
.arg("--bin")
.arg(bin_name)
.status()?;

if !status.success() {
eprintln!("Failed to build in {}", path);
std::process::exit(1);
}

// This is the path to the newly-built binary.
// See https://doc.rust-lang.org/cargo/guide/build-cache.html for details.
let target_bin = target_dir
.join(target_name)
.join(std::env::var("PROFILE").unwrap())
.join(bin_name);

// And here's where we'd like to place the final (stripped) binary
let out_bin = out_dir.join("bin").join(bin_name);

// Strip the binary
let status = Command::new("strip")
.arg("--strip-unneeded")
.arg("-o")
.arg(&out_bin)
.arg(&target_bin)
.status()?;

// Failing that, just copy it into place
if !status.success() {
println!("cargo:warning=Failed to run `strip` on {:?}", target_bin);
std::fs::rename(&target_bin, &out_bin)?;
}

Ok(())
}

fn create(path: &Path) {
match std::fs::create_dir(&path) {
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => {}
Expand All @@ -118,7 +223,7 @@ fn create(path: &Path) {
}
}

fn main() {
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("cargo:rerun-if-env-changed=OUT_DIR");
println!("cargo:rerun-if-env-changed=PROFILE");

Expand All @@ -142,128 +247,39 @@ fn main() {

build_cc_tests(&Path::new(CRATE).join(TEST_BINS_IN), &out_dir_bin);
build_rs_tests(&Path::new(CRATE).join(TEST_BINS_IN), &out_dir_bin);
#[cfg(feature = "wasmldr")]
build_wasm_tests(&Path::new(CRATE).join("tests/wasm"), &out_dir_bin);

let profile: &[&str] = match std::env::var("PROFILE").unwrap().as_str() {
"release" => &["--release"],
_ => &[],
};

let target_name = "x86_64-unknown-linux-musl";

let filtered_env: HashMap<String, String> = std::env::vars()
.filter(|&(ref k, _)| {
k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH" || k == "RUSTUP_HOME"
})
.collect();
let target = "x86_64-unknown-linux-musl";

// internal crates are not included, if there is a `Cargo.toml` file
// trick cargo by renaming the `Cargo.toml` to `Cargo.tml` before
// publishing and rename it back here.
for entry in std::fs::read_dir("internal").unwrap() {
let path = entry.unwrap().path();
for entry in std::fs::read_dir("internal")? {
let path = entry?.path();

let cargo_toml = path.join("Cargo.toml");
let cargo_tml = path.join("Cargo.tml");

if cargo_tml.exists() {
std::fs::copy(cargo_tml, cargo_toml).unwrap();
std::fs::copy(cargo_tml, cargo_toml)?;
}
}

for entry in std::fs::read_dir("internal").unwrap() {
let path_buf = entry.unwrap().path();

let shim_name = path_buf.clone();
let shim_name = shim_name
.file_name()
.unwrap()
.to_os_string()
.into_string()
.unwrap();

let shim_out_dir = out_dir.join(&path_buf);
let dir_name = path.file_name().unwrap().to_str().unwrap_or_default();

let path: String = path_buf.into_os_string().into_string().unwrap();
match dir_name {
#[cfg(feature = "wasmldr")]
"wasmldr" => cargo_build_bin(&path, &out_dir, target, "wasmldr")?,

println!("cargo:rerun-if-changed={}/Cargo.tml", path);
println!("cargo:rerun-if-changed={}/Cargo.toml", path);
println!("cargo:rerun-if-changed={}/Cargo.lock", path);
println!("cargo:rerun-if-changed={}/layout.ld", path);
println!("cargo:rerun-if-changed={}/.cargo/config", path);
#[cfg(feature = "backend-kvm")]
"shim-sev" => cargo_build_bin(&path, &out_dir, target, "shim-sev")?,

rerun_src(&path);
#[cfg(feature = "backend-sgx")]
"shim-sgx" => cargo_build_bin(&path, &out_dir, target, "shim-sgx")?,

if !shim_name.starts_with("shim-") {
continue;
}

#[cfg(not(any(feature = "backend-kvm")))]
if shim_name.starts_with("shim-sev") {
continue;
}

#[cfg(not(feature = "backend-sgx"))]
if shim_name.starts_with("shim-sgx") {
continue;
}

let target_dir = shim_out_dir.clone().into_os_string().into_string().unwrap();

let stdout: Stdio = OpenOptions::new()
.write(true)
.open("/dev/tty")
.map(Stdio::from)
.unwrap_or_else(|_| Stdio::inherit());

let stderr: Stdio = OpenOptions::new()
.write(true)
.open("/dev/tty")
.map(Stdio::from)
.unwrap_or_else(|_| Stdio::inherit());

let status = Command::new("cargo")
.current_dir(&path)
.env_clear()
.envs(&filtered_env)
.stdout(stdout)
.stderr(stderr)
.arg("+nightly")
.arg("build")
.args(profile)
.arg("--target-dir")
.arg(&target_dir)
.arg("--target")
.arg(target_name)
.arg("--bin")
.arg(&shim_name)
.status()
.expect("failed to build shim");

if !status.success() {
eprintln!("Failed to build shim {}", path);
std::process::exit(1);
}

let out_bin = out_dir_bin.join(&shim_name);

let shim_out_bin = shim_out_dir
.join(&target_name)
.join(&std::env::var("PROFILE").unwrap())
.join(&shim_name);

let status = Command::new("strip")
.arg("--strip-unneeded")
.arg("-o")
.arg(&out_bin)
.arg(&shim_out_bin)
.status();

match status {
Ok(status) if status.success() => {}
_ => {
println!("cargo:warning=Failed to run `strip` on {:?}", &shim_out_bin);
std::fs::rename(&shim_out_bin, &out_bin).expect("move failed")
}
_ => continue,
}
}

Ok(())
}
2 changes: 1 addition & 1 deletion internal/shim-sev/layout.ld
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ reset_vector = 0xFFFFF000;
_ENARX_SHIM_START = reset_vector;
_ENARX_SALLYPORT_START = _ENARX_SHIM_START - _ENARX_SALLYPORT_SIZE - 2 * CONSTANT(COMMONPAGESIZE);
_ENARX_SALLYPORT_END = _ENARX_SALLYPORT_START + _ENARX_SALLYPORT_SIZE;
_ENARX_EXEC_LEN = 4M;
_ENARX_EXEC_LEN = 128M;

ASSERT((_ENARX_SHIM_START >= (3 * 0x40000000)), "SHIM_START is too low for current initial identity page table")
ASSERT((_ENARX_EXEC_START < (6 * 0x40000000)), "SHIM is too large for current initial identity page table")
Expand Down
35 changes: 35 additions & 0 deletions internal/wasmldr/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[package]
name = "wasmldr"
version = "0.2.0"
authors = ["Will Woods <will@profian.com>"]
edition = "2018"
license = "Apache-2.0"
description = "Enarx WebAssembly Loader"
readme = "README.md"

# TODO: merge these into the toplevel actions/gitignore
exclude = [ ".gitignore", ".github/*" ]

[[bin]]
name = "wasmldr"

[dependencies]
wasmtime = { version = "0.30", default-features = false, features = ["cranelift"] }
wasmtime-wasi = { version = "0.30", default-features = false, features = ["sync"] }
wasi-common = { version = "0.30", default-features = false }
wasmparser = "0.80"
structopt = { version = "0.3", default-features = false }
anyhow = "1.0"
env_logger = { version = "0.9", default-features = false }
log = "0.4"

[dev-dependencies]
wat = "1.0"

[profile.release]
incremental = false
codegen-units = 1
panic = "abort"
lto = true
debug = 1
opt-level = "s"
Loading