From 92d3537abb36a1c8c269fc96b9a962be40745a99 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Sat, 12 Dec 2020 21:38:23 -0600 Subject: [PATCH] Add wasi-exec-model cg option for emitting wasi reactors --- compiler/rustc_codegen_ssa/src/back/link.rs | 1 + compiler/rustc_codegen_ssa/src/back/linker.rs | 11 ++++++++++ compiler/rustc_interface/src/tests.rs | 3 ++- compiler/rustc_session/src/config.rs | 2 ++ compiler/rustc_session/src/options.rs | 20 ++++++++++++++++++- compiler/rustc_session/src/session.rs | 8 ++++++++ compiler/rustc_target/src/spec/crt_objects.rs | 20 ++++++++++--------- compiler/rustc_target/src/spec/mod.rs | 6 +++++- src/bootstrap/compile.rs | 18 +++++++++-------- 9 files changed, 69 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 70cf876a08a..80b92d3a72c 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -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, diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 3df956c465e..bb35e7ec894 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -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 @@ -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"); + } } } @@ -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"); + } } } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2273266a3ff..62f620e0639 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -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; @@ -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] diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 54abb65dc38..31fc13d2372 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -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; @@ -2141,6 +2142,7 @@ crate mod dep_tracking { impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); + impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 74578f2dc17..bc1d862b160 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -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)] @@ -708,6 +709,15 @@ macro_rules! options { None => false, } } + + fn parse_wasi_exec_model(slot: &mut Option, v: Option<&str>) -> bool { + match v { + Some("command") => *slot = Some(WasiExecModel::Command), + Some("reactor") => *slot = Some(WasiExecModel::Reactor), + _ => return false, + } + true + } } ) } @@ -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 = (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, } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 4e269f3172c..93c619c4054 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -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 . diff --git a/compiler/rustc_target/src/spec/crt_objects.rs b/compiler/rustc_target/src/spec/crt_objects.rs index 76c0bf419e8..32da16a2d8c 100644 --- a/compiler/rustc_target/src/spec/crt_objects.rs +++ b/compiler/rustc_target/src/spec/crt_objects.rs @@ -5,15 +5,16 @@ //! The `crtx` ones are generally distributed with libc and the `begin/end` ones with gcc. //! See 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 | //! |-----------------------|---------------|---------------|----------------|--------|------| @@ -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"]), ]) } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 8d749493d0a..f0ef15e1a39 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -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 { @@ -418,6 +420,7 @@ impl LinkOutputKind { LinkOutputKind::StaticPicExe => "static-pic-exe", LinkOutputKind::DynamicDylib => "dynamic-dylib", LinkOutputKind::StaticDylib => "static-dylib", + LinkOutputKind::WasiReactorExe => "wasi-reactor-exe", } } @@ -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, }) } @@ -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(|| diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index cdad1cb4d49..c142c43c98d 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -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);