Skip to content

DL support for 1.84 toolchain #15

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

Open
wants to merge 1 commit into
base: wasix-1.84.0
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
18 changes: 18 additions & 0 deletions build-wasix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

set -euo pipefail

cd src/llvm-project
git status | grep WebAssemblyISelLowering.cpp &> /dev/null
if [ $? -ne 0 ]; then
git apply ../../wasix-llvm.patch
fi
cd ../..

./x.py build --target=wasm32-wasmer-wasi --stage 2
./x.py build --target=wasm32-wasmer-wasi-dl --stage 2

rustup toolchain uninstall wasix-dev
rustup toolchain link wasix-dev ./build/host/stage2

echo Done
24 changes: 18 additions & 6 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::iter::Iterator;
use std::collections::BTreeSet;
use std::ffi::OsString;
use std::fs::{File, OpenOptions, read};
Expand Down Expand Up @@ -1116,16 +1117,22 @@ fn link_natively(
if sess.target.is_like_osx {
let stripcmd = "rust-objcopy";
match (strip, crate_type) {
(Strip::Debuginfo, _) => {
strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("--strip-debug"))
}
(Strip::Debuginfo, _) => strip_symbols_with_external_utility(
sess,
stripcmd,
out_filename,
Some("--strip-debug"),
),
// Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988)
(Strip::Symbols, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) => {
strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-x"))
}
(Strip::Symbols, _) => {
strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("--strip-all"))
}
(Strip::Symbols, _) => strip_symbols_with_external_utility(
sess,
stripcmd,
out_filename,
Some("--strip-all"),
),
(Strip::None, _) => {}
}
}
Expand Down Expand Up @@ -2986,6 +2993,11 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
}

fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
if sess.target.is_like_wasm && lib.name.as_str() == "c" {
// For wasm targets, WasmLd decides whether to link libc based on
// the output kind, so we skip it here.
return false;
}
match lib.cfg {
Some(ref cfg) => rustc_attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
None => true,
Expand Down
59 changes: 51 additions & 8 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ impl<'a> WasmLd<'a> {
// symbols are how the TLS segments are initialized and configured.
let mut wasm_ld = WasmLd { cmd, sess };
if sess.target_features.contains(&sym::atomics) {
wasm_ld.link_args(&["--shared-memory", "--max-memory=1073741824", "--import-memory"]);
wasm_ld.link_args(&["--shared-memory", "--max-memory=4294967296", "--import-memory"]);
if sess.target.os == "unknown" || sess.target.os == "none" {
wasm_ld.link_args(&[
"--export=__wasm_init_tls",
Expand All @@ -1304,11 +1304,38 @@ impl<'a> Linker for WasmLd<'a> {
_out_filename: &Path,
) {
match output_kind {
LinkOutputKind::DynamicNoPicExe
| LinkOutputKind::DynamicPicExe
| LinkOutputKind::StaticNoPicExe
| LinkOutputKind::StaticPicExe => {}
LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => {
LinkOutputKind::DynamicNoPicExe | LinkOutputKind::StaticNoPicExe => {}
LinkOutputKind::StaticPicExe | LinkOutputKind::DynamicPicExe => {
// FIXME: The wasm32-wasmer-wasi-dl toolchain produces broken executables
// right now, because the start function isn't linked correctly. Instead of
// _start calling the rust main function, it calls __main_void from libc,
// which is broken because rustc does not generate a __main_argc_argv.
// ... probably because we're linking in libc's _start and overriding rustc's?

self.link_args(["-pie", "--export-all", "--no-gc-sections"]);

// We link and export all of libc, as well as all of rust's stdlib into dynamic
// executables, so that side modules can just link against the existing code at
// runtime. This has two benefits:
// * Reduced code size for side modules
// * More importantly, static and thread-local variables will exist only once.
// This is especially important for libc, which stores things such as the
// state of its memory allocator (malloc et al.) in static variables.
let whole_archive = true;
let verbatim = false; // No effect for WasmLd
self.link_staticlib_by_name("c", verbatim, whole_archive);
self.link_staticlib_by_name("resolv", verbatim, whole_archive);
self.link_staticlib_by_name("rt", verbatim, whole_archive);
self.link_staticlib_by_name("m", verbatim, whole_archive);
self.link_staticlib_by_name("pthread", verbatim, whole_archive);
self.link_staticlib_by_name("util", verbatim, whole_archive);
self.link_staticlib_by_name("wasi-emulated-mman", verbatim, whole_archive);
self.link_staticlib_by_name("common-tag-stubs", verbatim, whole_archive);
}
LinkOutputKind::DynamicDylib => {
self.link_args(["--no-entry", "-shared", "--unresolved-symbols=import-dynamic"]);
}
LinkOutputKind::StaticDylib => {
self.link_arg("--no-entry");
}
LinkOutputKind::WasiReactorExe => {
Expand Down Expand Up @@ -1394,7 +1421,7 @@ impl<'a> Linker for WasmLd<'a> {

fn no_default_libraries(&mut self) {}

fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
for sym in symbols {
self.link_args(&["--export", sym]);
}
Expand All @@ -1403,7 +1430,23 @@ impl<'a> Linker for WasmLd<'a> {
// symbols explicitly passed via the `--export` flags above and hides all
// others. Various bits and pieces of wasm32-unknown-unknown tooling use
// this, so be sure these symbols make their way out of the linker as well.
self.link_args(&["--export=__heap_base", "--export=__data_end", "--export=__stack_pointer"]);
self.link_args(&[
"--export=__wasm_init_tls",
"--export=__tls_size",
"--export=__tls_align",
"--export=__tls_base",
"--export=__wasm_call_ctors",
"--export=__wasm_signal",
"--export-if-defined=__wasm_apply_data_relocs",
]);

if matches!(crate_type, CrateType::Executable) {
self.link_args(&[
"--export-if-defined=__stack_pointer",
"--export-if-defined=__heap_base",
"--export-if-defined=__data_end",
]);
}
}

fn subsystem(&mut self, _subsystem: &str) {}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/crt_objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,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, &["scrt1.o"]),
(LinkOutputKind::StaticDylib, &["scrt1.o"]),
(LinkOutputKind::WasiReactorExe, &["crt1-reactor.o"]),
])
}
Expand Down
15 changes: 8 additions & 7 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,9 +1333,9 @@ impl StackProbeType {
.and_then(|o| o.as_array())
.ok_or_else(|| "expected `min-llvm-version-for-inline` to be an array")?;
let mut iter = min_version.into_iter().map(|v| {
let int = v.as_u64().ok_or_else(|| {
"expected `min-llvm-version-for-inline` values to be integers"
})?;
let int = v.as_u64().ok_or_else(
|| "expected `min-llvm-version-for-inline` values to be integers",
)?;
u32::try_from(int)
.map_err(|_| "`min-llvm-version-for-inline` values don't convert to u32")
});
Expand Down Expand Up @@ -1809,6 +1809,7 @@ supported_targets! {
("wasm32-wasip2", wasm32_wasip2),
("wasm32-wasip1-threads", wasm32_wasip1_threads),
("wasm32-wasmer-wasi", wasm32_wasmer_wasi),
("wasm32-wasmer-wasi-dl", wasm32_wasmer_wasi_dl),
("wasm64-unknown-emscripten", wasm64_unknown_emscripten),
("wasm64-unknown-unknown", wasm64_unknown_unknown),
("wasm64-wasmer-wasi", wasm64_wasmer_wasi),
Expand Down Expand Up @@ -3462,10 +3463,10 @@ impl Target {

// Each field should have been read using `Json::remove` so any keys remaining are unused.
let remaining_keys = obj.keys();
Ok((base, TargetWarnings {
unused_fields: remaining_keys.cloned().collect(),
incorrect_type,
}))
Ok((
base,
TargetWarnings { unused_fields: remaining_keys.cloned().collect(), incorrect_type },
))
}

/// Load a built-in target
Expand Down
29 changes: 19 additions & 10 deletions compiler/rustc_target/src/spec/targets/wasm32_wasmer_wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,31 @@
//! best we can with this target. Don't start relying on too much here unless
//! you know what you're getting in to!

use crate::spec::{base, crt_objects, Cc, LinkSelfContainedDefault, LinkerFlavor, Target};
use crate::spec::{Cc, LinkSelfContainedDefault, LinkerFlavor, Target, base, crt_objects};

pub(crate) fn target() -> Target {
macro_rules! args {
($prefix:literal) => {
&[
// We need shared memory for multithreading
concat!($prefix, "--shared-memory"),
concat!($prefix, "--import-memory"),
concat!($prefix, "--export-dynamic"),
concat!($prefix, "--no-check-features"),
concat!($prefix, "-mllvm"),
concat!($prefix, "--wasm-enable-sjlj"),
]
};
}

let mut options = base::wasm::options();

options.os = "wasi".into();
options.vendor = "wasmer".into();
options.add_pre_link_args(
LinkerFlavor::WasmLld(Cc::Yes),
&[
"--target=wasm32-wasi",
// We need shared memory for multithreading
"--shared-memory",
"--no-check-features",
],
);
options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]);

options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,"));
options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), args!(""));

options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_target/src/spec/targets/wasm32_wasmer_wasi_dl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//! `wasm32-wasmer-wasi` with support for dynamic linking.

use crate::spec::{RelocModel, Target, TlsModel};

pub(crate) fn target() -> Target {
let mut target = super::wasm32_wasmer_wasi::target();

target.env = "dl".into();

target.options.dll_prefix = "lib".into();
target.options.dll_suffix = ".so".into();

target.options.relocation_model = RelocModel::Pic;
target.options.tls_model = TlsModel::GeneralDynamic;
target.options.crt_static_default = false;
target.options.position_independent_executables = true;

target
}
10 changes: 5 additions & 5 deletions config.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
change-id = 125535

[build]
target = ["wasm32-wasmer-wasi", "wasm64-wasmer-wasi"]
target = ["wasm32-wasmer-wasi", "wasm32-wasmer-wasi-dl"]
extended = true
tools = [ "clippy", "rustfmt" ]
tools = ["cargo", "clippy", "rustfmt"]
configure-args = []

[rust]
Expand All @@ -14,7 +14,7 @@ llvm-tools = true
download-ci-llvm = false

[target.wasm32-wasmer-wasi]
wasi-root = "../wasix-libc/sysroot32"
wasi-root = "../wasix-libc/sysroot32-eh"

[target.wasm64-wasmer-wasi]
wasi-root = "../wasix-libc/sysroot64"
[target.wasm32-wasmer-wasi-dl]
wasi-root = "../wasix-libc/sysroot32-ehpic"
18 changes: 15 additions & 3 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
addr2line = { version = "0.22.0", optional = true, default-features = false }

[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
libc = { git = "https://github.com/wasix-org/libc.git", branch = "wasix-0.2.164", version = "0.2.164", default-features = false, features = ['rustc-dep-of-std'], public = true }
libc = { git = "https://github.com/wasix-org/libc.git", branch = "wasix-0.2.164", version = "0.2.164", default-features = false, features = [
'rustc-dep-of-std',
], public = true }

[target.'cfg(all(not(target_os = "aix"), not(all(windows, target_env = "msvc", not(target_vendor = "uwp")))))'.dependencies]
object = { version = "0.36.0", default-features = false, optional = true, features = [
Expand Down Expand Up @@ -80,10 +82,19 @@ wasi = { version = "0.11.0", features = [
], default-features = false }

[target.wasm32-wasmer-wasi.dependencies]
wasi = { package = "wasix", version = "0.13.0", features = ['rustc-dep-of-std'], default-features = false, public = true }
wasi = { package = "wasix", version = "0.13.0", features = [
'rustc-dep-of-std',
], default-features = false, public = true }

[target.wasm32-wasmer-wasi-dl.dependencies]
wasi = { package = "wasix", version = "0.13.0", features = [
'rustc-dep-of-std',
], default-features = false, public = true }

[target.wasm64-wasmer-wasi.dependencies]
wasi = { package = "wasix", version = "0.13.0", features = ['rustc-dep-of-std'], default-features = false, public = true }
wasi = { package = "wasix", version = "0.13.0", features = [
'rustc-dep-of-std',
], default-features = false, public = true }

[target.'cfg(target_os = "uefi")'.dependencies]
r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] }
Expand Down Expand Up @@ -145,6 +156,7 @@ check-cfg = [
'cfg(bootstrap)',
'cfg(target_arch, values("xtensa"))',
'cfg(target_vendor, values("wasmer"))',
'cfg(target_env, values("dl"))',
# std use #[path] imports to portable-simd `std_float` crate
# and to the `backtrace` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg
Expand Down
23 changes: 22 additions & 1 deletion src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,28 @@ fn copy_self_contained_objects(
target.triple
)
});
for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] {
let mut files = vec!["libc.a", "crt1-command.o", "crt1-reactor.o"];
if target.contains("-dl") {
files.extend([
// Needed for DL side modules.
"scrt1.o",
// Need to bring these over for DL main module builds, so we can embed them.
"libcommon-tag-stubs.a",
"libcrypt.a",
"libwasi-emulated-mman.a",
"libresolv.a",
"librt.a",
"libm.a",
"libpthread.a",
"libutil.a",
// We don't link c++ libs in, but we bring them over anyway so that, when
// a rust program needs to load C++-based dylibs, the user can link these
// in manually via linker flags.
"libc++.a",
"libc++abi.a",
]);
}
for obj in files {
copy_and_stamp(
builder,
&libdir_self_contained,
Expand Down
Loading
Loading