Skip to content

Add a -Zwasi-exec-model codegen option for emitting WASI reactors #79997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 12, 2021
Merged
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
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,7 @@ fn exec_linker(

fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
let kind = match (crate_type, sess.crt_static(Some(crate_type)), sess.relocation_model()) {
(CrateType::Executable, _, _) if sess.is_wasi_reactor() => LinkOutputKind::WasiReactorExe,
(CrateType::Executable, false, RelocModel::Pic) => LinkOutputKind::DynamicPicExe,
(CrateType::Executable, false, _) => LinkOutputKind::DynamicNoPicExe,
(CrateType::Executable, true, RelocModel::Pic) => LinkOutputKind::StaticPicExe,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ impl<'a> Linker for GccLinker<'a> {
self.cmd.arg("-static");
self.build_dylib(out_filename);
}
LinkOutputKind::WasiReactorExe => {
self.linker_arg("--entry");
self.linker_arg("_initialize");
}
}
// VxWorks compiler driver introduced `--static-crt` flag specifically for rustc,
// it switches linking for libc and similar system libraries to static without using
Expand Down Expand Up @@ -662,6 +666,9 @@ impl<'a> Linker for MsvcLinker<'a> {
arg.push(out_filename.with_extension("dll.lib"));
self.cmd.arg(arg);
}
LinkOutputKind::WasiReactorExe => {
panic!("can't link as reactor on non-wasi target");
}
}
}

Expand Down Expand Up @@ -1085,6 +1092,10 @@ impl<'a> Linker for WasmLd<'a> {
LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => {
self.cmd.arg("--no-entry");
}
LinkOutputKind::WasiReactorExe => {
self.cmd.arg("--entry");
self.cmd.arg("_initialize");
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_session::config::{build_configuration, build_session_options, to_crate
use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes};
use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
use rustc_session::config::{
Externs, OutputType, OutputTypes, SanitizerSet, SymbolManglingVersion,
Externs, OutputType, OutputTypes, SanitizerSet, SymbolManglingVersion, WasiExecModel,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
Expand Down Expand Up @@ -597,6 +597,7 @@ fn test_debugging_options_tracking_hash() {
tracked!(unleash_the_miri_inside_of_you, true);
tracked!(use_ctors_section, Some(true));
tracked!(verify_llvm_ir, true);
tracked!(wasi_exec_model, Some(WasiExecModel::Reactor));
}

#[test]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2086,6 +2086,7 @@ crate mod dep_tracking {
SymbolManglingVersion, TrimmedDefPaths,
};
use crate::lint;
use crate::options::WasiExecModel;
use crate::utils::NativeLibKind;
use rustc_feature::UnstableFeatures;
use rustc_span::edition::Edition;
Expand Down Expand Up @@ -2141,6 +2142,7 @@ crate mod dep_tracking {
impl_dep_tracking_hash_via_hash!(Option<RelocModel>);
impl_dep_tracking_hash_via_hash!(Option<CodeModel>);
impl_dep_tracking_hash_via_hash!(Option<TlsModel>);
impl_dep_tracking_hash_via_hash!(Option<WasiExecModel>);
impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
Expand Down
20 changes: 19 additions & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ macro_rules! options {
pub const parse_tls_model: &str =
"one of supported TLS models (`rustc --print tls-models`)";
pub const parse_target_feature: &str = parse_string;
pub const parse_wasi_exec_model: &str = "either `command` or `reactor`";
}

#[allow(dead_code)]
Expand Down Expand Up @@ -708,6 +709,15 @@ macro_rules! options {
None => false,
}
}

fn parse_wasi_exec_model(slot: &mut Option<WasiExecModel>, v: Option<&str>) -> bool {
match v {
Some("command") => *slot = Some(WasiExecModel::Command),
Some("reactor") => *slot = Some(WasiExecModel::Reactor),
_ => return false,
}
true
}
}
) }

Expand Down Expand Up @@ -1147,9 +1157,17 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"in general, enable more debug printouts (default: no)"),
verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
"verify LLVM IR (default: no)"),
wasi_exec_model: Option<WasiExecModel> = (None, parse_wasi_exec_model, [TRACKED],
"whether to build a wasi command or reactor"),

// This list is in alphabetical order.
//
// If you add a new option, please update:
// - src/librustc_interface/tests.rs
// - compiler/rustc_interface/src/tests.rs
}

#[derive(Clone, Hash)]
pub enum WasiExecModel {
Command,
Reactor,
}
8 changes: 8 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,14 @@ impl Session {
self.opts.debugging_opts.tls_model.unwrap_or(self.target.tls_model)
}

pub fn is_wasi_reactor(&self) -> bool {
self.target.options.os == "wasi"
&& matches!(
self.opts.debugging_opts.wasi_exec_model,
Some(config::WasiExecModel::Reactor)
)
}

pub fn must_not_eliminate_frame_pointers(&self) -> bool {
// "mcount" function relies on stack pointer.
// See <https://sourceware.org/binutils/docs/gprof/Implementation.html>.
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_target/src/spec/crt_objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
//! The `crtx` ones are generally distributed with libc and the `begin/end` ones with gcc.
//! See <https://dev.gentoo.org/~vapier/crt.txt> for some more details.
//!
//! | Pre-link CRT objects | glibc | musl | bionic | mingw | wasi |
//! |----------------------|------------------------|------------------------|------------------|-------------------|------|
//! | dynamic-nopic-exe | crt1, crti, crtbegin | crt1, crti, crtbegin | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | dynamic-pic-exe | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | static-nopic-exe | crt1, crti, crtbeginT | crt1, crti, crtbegin | crtbegin_static | crt2, crtbegin | crt1 |
//! | static-pic-exe | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | dynamic-dylib | crti, crtbeginS | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
//! | static-dylib (gcc) | crti, crtbeginT | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | - |
//! | Pre-link CRT objects | glibc | musl | bionic | mingw | wasi |
//! |----------------------|------------------------|------------------------|------------------|-------------------|--------------|
//! | dynamic-nopic-exe | crt1, crti, crtbegin | crt1, crti, crtbegin | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | dynamic-pic-exe | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | static-nopic-exe | crt1, crti, crtbeginT | crt1, crti, crtbegin | crtbegin_static | crt2, crtbegin | crt1 |
//! | static-pic-exe | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | dynamic-dylib | crti, crtbeginS | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
//! | static-dylib (gcc) | crti, crtbeginT | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | - |
//! | wasi-reactor-exe | N/A | N/A | N/A | N/A | crt1-reactor |
//!
//! | Post-link CRT objects | glibc | musl | bionic | mingw | wasi |
//! |-----------------------|---------------|---------------|----------------|--------|------|
Expand Down Expand Up @@ -105,6 +106,7 @@ pub(super) fn pre_wasi_fallback() -> CrtObjects {
(LinkOutputKind::DynamicPicExe, &["crt1.o"]),
(LinkOutputKind::StaticNoPicExe, &["crt1.o"]),
(LinkOutputKind::StaticPicExe, &["crt1.o"]),
(LinkOutputKind::WasiReactorExe, &["crt1-reactor.o"]),
])
}

Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ pub enum LinkOutputKind {
DynamicDylib,
/// Dynamic library with bundled libc ("statically linked").
StaticDylib,
/// WASI module with a lifetime past the _initialize entry point
WasiReactorExe,
}

impl LinkOutputKind {
Expand All @@ -418,6 +420,7 @@ impl LinkOutputKind {
LinkOutputKind::StaticPicExe => "static-pic-exe",
LinkOutputKind::DynamicDylib => "dynamic-dylib",
LinkOutputKind::StaticDylib => "static-dylib",
LinkOutputKind::WasiReactorExe => "wasi-reactor-exe",
}
}

Expand All @@ -429,6 +432,7 @@ impl LinkOutputKind {
"static-pic-exe" => LinkOutputKind::StaticPicExe,
"dynamic-dylib" => LinkOutputKind::DynamicDylib,
"static-dylib" => LinkOutputKind::StaticDylib,
"wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
_ => return None,
})
}
Expand Down Expand Up @@ -1377,7 +1381,7 @@ impl Target {
let kind = LinkOutputKind::from_str(&k).ok_or_else(|| {
format!("{}: '{}' is not a valid value for CRT object kind. \
Use '(dynamic,static)-(nopic,pic)-exe' or \
'(dynamic,static)-dylib'", name, k)
'(dynamic,static)-dylib' or 'wasi-reactor-exe'", name, k)
})?;

let v = v.as_array().ok_or_else(||
Expand Down
18 changes: 10 additions & 8 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,16 @@ fn copy_self_contained_objects(
}
} else if target.ends_with("-wasi") {
let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi");
copy_and_stamp(
builder,
&libdir_self_contained,
&srcdir,
"crt1.o",
&mut target_deps,
DependencyType::TargetSelfContained,
);
for &obj in &["crt1.o", "crt1-reactor.o"] {
copy_and_stamp(
builder,
&libdir_self_contained,
&srcdir,
obj,
&mut target_deps,
DependencyType::TargetSelfContained,
);
}
} else if target.contains("windows-gnu") {
for obj in ["crt2.o", "dllcrt2.o"].iter() {
let src = compiler_file(builder, builder.cc(target), target, obj);
Expand Down