mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
Rollup merge of #79997 - coolreader18:wasm-reactor, r=alexcrichton
Emit a reactor for cdylib target on wasi Fixes #79199, and relevant to #73432 Implements wasi reactors, as described in WebAssembly/WASI#13 and [`design/application-abi.md`](https://github.com/WebAssembly/WASI/blob/master/design/application-abi.md) Empty `lib.rs`, `lib.crate-type = ["cdylib"]`: ```shell $ cargo +reactor build --release --target wasm32-wasi Compiling wasm-reactor v0.1.0 (/home/coolreader18/wasm-reactor) Finished release [optimized] target(s) in 0.08s $ wasm-dis target/wasm32-wasi/release/wasm_reactor.wasm >reactor.wat ``` `reactor.wat`: ```wat (module (type $none_=>_none (func)) (type $i32_=>_none (func (param i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (import "wasi_snapshot_preview1" "fd_prestat_get" (func $__wasi_fd_prestat_get (param i32 i32) (result i32))) (import "wasi_snapshot_preview1" "fd_prestat_dir_name" (func $__wasi_fd_prestat_dir_name (param i32 i32 i32) (result i32))) (import "wasi_snapshot_preview1" "proc_exit" (func $__wasi_proc_exit (param i32))) (import "wasi_snapshot_preview1" "environ_sizes_get" (func $__wasi_environ_sizes_get (param i32 i32) (result i32))) (import "wasi_snapshot_preview1" "environ_get" (func $__wasi_environ_get (param i32 i32) (result i32))) (memory $0 17) (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 1048576)) (global $global$1 i32 (i32.const 1049096)) (global $global$2 i32 (i32.const 1049096)) (export "memory" (memory $0)) (export "_initialize" (func $_initialize)) (export "__data_end" (global $global$1)) (export "__heap_base" (global $global$2)) (func $__wasm_call_ctors (call $__wasilibc_initialize_environ_eagerly) (call $__wasilibc_populate_preopens) ) (func $_initialize (call $__wasm_call_ctors) ) (func $malloc (param $0 i32) (result i32) (call $dlmalloc (local.get $0) ) ) ;; lots of dlmalloc, memset/memcpy, & libpreopen code ) ``` I went with repurposing cdylib because I figured that it doesn't make much sense to have a wasi shared library that can't be initialized, and even if someone was using it adding an `_initialize` export is a very small change.
This commit is contained in:
commit
1d83f9828f
@ -1276,6 +1276,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,
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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]
|
||||
|
@ -2172,6 +2172,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;
|
||||
@ -2227,6 +2228,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>);
|
||||
|
@ -279,6 +279,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)]
|
||||
@ -722,6 +723,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
|
||||
}
|
||||
}
|
||||
) }
|
||||
|
||||
@ -1166,9 +1176,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,
|
||||
}
|
||||
|
@ -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>.
|
||||
|
@ -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 |
|
||||
//! |-----------------------|---------------|---------------|----------------|--------|------|
|
||||
@ -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"]),
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -408,6 +408,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 {
|
||||
@ -419,6 +421,7 @@ impl LinkOutputKind {
|
||||
LinkOutputKind::StaticPicExe => "static-pic-exe",
|
||||
LinkOutputKind::DynamicDylib => "dynamic-dylib",
|
||||
LinkOutputKind::StaticDylib => "static-dylib",
|
||||
LinkOutputKind::WasiReactorExe => "wasi-reactor-exe",
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,6 +433,7 @@ impl LinkOutputKind {
|
||||
"static-pic-exe" => LinkOutputKind::StaticPicExe,
|
||||
"dynamic-dylib" => LinkOutputKind::DynamicDylib,
|
||||
"static-dylib" => LinkOutputKind::StaticDylib,
|
||||
"wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@ -1378,7 +1382,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(||
|
||||
|
@ -188,14 +188,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);
|
||||
|
Loading…
Reference in New Issue
Block a user