From 8c69f740dae426e7dc9e5ccac6cf2d3017f16832 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 14 Feb 2023 13:10:09 -0800 Subject: [PATCH] Change Wasm's `cdylib` etc. to be a "reactor". Use `--entry` `_initialize` on `cdylib` and similar library types on Wasm targets. This is a change in how constructor functions have at least sometimes been handled. It will mean that there's an exported `_initialize` function which calls the static constructors, and it must be called from the outside before any other export is accessed. Rust doesn't officially have static constructors, but C++ does and C has not-uncommonly-used extensions that do, and there are crates in Rust that provide static-constructor functionality. Some Wasm embeddings automatically call the `_initialize` function if present because it is part of the [WASI Preview1 application ABI], though not all do. This does not implement support for dynamic linking. The format and behavior of `cdylib` and similar outputs may change in future compiler versions, especially as Wasm gains a stable dynamic linking format. What this does do, is make `cdylib` work more like what many people have been assuming `cylib` does on Wasm. It produces a Wasm module that doesn't have a main function that you can instantiate and call exports on, but which now also supports static constructors by having an `_initialize` function that you or your engine must call first. [WASI Preview1 application ABI]: https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md --- compiler/rustc_codegen_ssa/src/back/linker.rs | 7 +++---- compiler/rustc_target/src/spec/crt_objects.rs | 14 ++++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index eaf1e9817c203..2e835e972e1d1 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1207,10 +1207,9 @@ impl<'a> Linker for WasmLd<'a> { | LinkOutputKind::DynamicPicExe | LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => {} - LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => { - self.cmd.arg("--no-entry"); - } - LinkOutputKind::WasiReactorExe => { + LinkOutputKind::DynamicDylib + | LinkOutputKind::StaticDylib + | LinkOutputKind::WasiReactorExe => { self.cmd.arg("--entry"); self.cmd.arg("_initialize"); } diff --git a/compiler/rustc_target/src/spec/crt_objects.rs b/compiler/rustc_target/src/spec/crt_objects.rs index c126390f5a908..6c1bbb5610b48 100644 --- a/compiler/rustc_target/src/spec/crt_objects.rs +++ b/compiler/rustc_target/src/spec/crt_objects.rs @@ -7,13 +7,13 @@ //! //! | 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 | - | +//! | dynamic-nopic-exe | crt1, crti, crtbegin | crt1, crti, crtbegin | crtbegin_dynamic | crt2, crtbegin | crt1-command | +//! | dynamic-pic-exe | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1-command | +//! | static-nopic-exe | crt1, crti, crtbeginT | crt1, crti, crtbegin | crtbegin_static | crt2, crtbegin | crt1-command | +//! | static-pic-exe | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1-command | +//! | dynamic-dylib | crti, crtbeginS | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | crt1-reactor | //! | static-dylib (gcc) | crti, crtbeginT | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - | -//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | - | +//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | crt1-reactor | //! | wasi-reactor-exe | N/A | N/A | N/A | N/A | crt1-reactor | //! //! | Post-link CRT objects | glibc | musl | bionic | mingw | wasi | @@ -116,6 +116,8 @@ pub(super) fn pre_wasi_self_contained() -> CrtObjects { (LinkOutputKind::DynamicPicExe, &["crt1-command.o"]), (LinkOutputKind::StaticNoPicExe, &["crt1-command.o"]), (LinkOutputKind::StaticPicExe, &["crt1-command.o"]), + (LinkOutputKind::DynamicDylib, &["crt1-reactor.o"]), + (LinkOutputKind::StaticDylib, &["crt1-reactor.o"]), (LinkOutputKind::WasiReactorExe, &["crt1-reactor.o"]), ]) }