rustc_target/spec/base/linux_wasm.rs
1//! This target is a confluence of Linux and Wasm models, inheriting most
2//! aspects from their respective base targets
3
4use crate::spec::{
5 Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel,
6 add_link_args, crt_objects, cvs,
7};
8
9pub(crate) fn opts() -> TargetOptions {
10 macro_rules! args {
11 ($prefix:literal) => {
12 &[
13 // By default LLD only gives us one page of stack (64k) which is a
14 // little small. Default to a larger stack closer to other PC platforms
15 // (1MB) and users can always inject their own link-args to override this.
16 concat!($prefix, "-z"),
17 concat!($prefix, "stack-size=1048576"),
18 // By default LLD's memory layout is:
19 //
20 // 1. First, a blank page
21 // 2. Next, all static data
22 // 3. Finally, the main stack (which grows down)
23 //
24 // This has the unfortunate consequence that on stack overflows you
25 // corrupt static data and can cause some exceedingly weird bugs. To
26 // help detect this a little sooner we instead request that the stack is
27 // placed before static data.
28 //
29 // This means that we'll generate slightly larger binaries as references
30 // to static data will take more bytes in the ULEB128 encoding, but
31 // stack overflow will be guaranteed to trap as it underflows instead of
32 // corrupting static data.
33 concat!($prefix, "--stack-first"),
34 // FIXME we probably shouldn't pass this but instead pass an explicit list
35 // of symbols we'll allow to be undefined. We don't currently have a
36 // mechanism of knowing, however, which symbols are intended to be imported
37 // from the environment and which are intended to be imported from other
38 // objects linked elsewhere. This is a coarse approximation but is sure to
39 // hide some bugs and frustrate someone at some point, so we should ideally
40 // work towards a world where we can explicitly list symbols that are
41 // supposed to be imported and have all other symbols generate errors if
42 // they remain undefined.
43 concat!($prefix, "--allow-undefined"),
44 // LLD only implements C++-like demangling, which doesn't match our own
45 // mangling scheme. Tell LLD to not demangle anything and leave it up to
46 // us to demangle these symbols later. Currently rustc does not perform
47 // further demangling, but tools like twiggy and wasm-bindgen are intended
48 // to do so.
49 concat!($prefix, "--no-demangle"),
50 ]
51 };
52 }
53
54 let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!(""));
55 add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,"));
56
57 TargetOptions {
58 is_like_wasm: true,
59 families: cvs!["wasm", "unix"],
60 os: "linux".into(),
61 env: "musl".into(),
62
63 // we allow dynamic linking, but only cdylibs. Basically we allow a
64 // final library artifact that exports some symbols (a wasm module) but
65 // we don't allow intermediate `dylib` crate types
66 dynamic_linking: true,
67 only_cdylib: true,
68
69 // relatively self-explanatory!
70 exe_suffix: ".wasm".into(),
71 dll_prefix: "".into(),
72 dll_suffix: ".wasm".into(),
73 eh_frame_header: false,
74
75 max_atomic_width: Some(64),
76
77 // Unwinding doesn't work right now, so the whole target unconditionally
78 // defaults to panic=abort. Note that this is guaranteed to change in
79 // the future once unwinding is implemented. Don't rely on this as we're
80 // basically guaranteed to change it once WebAssembly supports
81 // exceptions.
82 panic_strategy: PanicStrategy::Abort,
83
84 // Symbol visibility takes care of this for the WebAssembly.
85 // Additionally the only known linker, LLD, doesn't support the script
86 // arguments just yet
87 limit_rdylib_exports: false,
88
89 // we use the LLD shipped with the Rust toolchain by default
90 linker: Some("rust-lld".into()),
91 linker_flavor: LinkerFlavor::WasmLld(Cc::No),
92
93 pre_link_args,
94
95 // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
96 //
97 // rust-lang/rust#104137: cannot blindly remove this without putting in
98 // some other way to compensate for lack of `-nostartfiles` in linker
99 // invocation.
100 link_self_contained: LinkSelfContainedDefault::True,
101 pre_link_objects_self_contained: crt_objects::pre_wasi_self_contained(),
102 post_link_objects_self_contained: crt_objects::post_wasi_self_contained(),
103
104 // This has no effect in LLVM 8 or prior, but in LLVM 9 and later when
105 // PIC code is implemented this has quite a drastic effect if it stays
106 // at the default, `pic`. In an effort to keep wasm binaries as minimal
107 // as possible we're defaulting to `static` for now, but the hope is
108 // that eventually we can ship a `pic`-compatible standard library which
109 // works with `static` as well (or works with some method of generating
110 // non-relative calls and such later on).
111 relocation_model: RelocModel::Static,
112
113 // When the atomics feature is activated then these two keys matter,
114 // otherwise they're basically ignored by the standard library. In this
115 // mode, however, the `#[thread_local]` attribute works (i.e.
116 // `has_thread_local`) and we need to get it to work by specifying
117 // `local-exec` as that's all that's implemented in LLVM today for wasm.
118 has_thread_local: true,
119 tls_model: TlsModel::LocalExec,
120
121 // Supporting Linux requires multithreading supported by Wasm's thread
122 // proposal
123 singlethread: false,
124
125 // gdb scripts don't work on wasm blobs
126 emit_debug_gdb_scripts: false,
127
128 // There's more discussion of this at
129 // https://bugs.llvm.org/show_bug.cgi?id=52442 but the general result is
130 // that this isn't useful for wasm and has tricky issues with
131 // representation, so this is disabled.
132 generate_arange_section: false,
133
134 // Right now this is a bit of a workaround but we're currently saying that
135 // the target by default has a static crt which we're taking as a signal
136 // for "use the bundled crt". If that's turned off then the system's crt
137 // will be used, but this means that default usage of this target doesn't
138 // need an external compiler but it's still interoperable with an external
139 // compiler if configured correctly.
140 crt_static_default: true,
141 crt_static_respected: true,
142
143 // Allow `+crt-static` to create a "cdylib" output which is just a wasm file
144 // without a main function.
145 crt_static_allows_dylibs: true,
146
147 // Wasm start ignores arguments -- relies on API call from interface.
148 main_needs_argc_argv: false,
149
150 // Wasm toolchains mangle the name of "main" to distinguish between different
151 // signatures.
152 entry_name: "__main_void".into(),
153
154 // Wasm Feature flags for supporting Linux
155 features: "+atomics,+bulk-memory,+mutable-globals,+sign-ext".into(),
156
157 ..Default::default()
158 }
159}