Skip to content

Commit a53a79f

Browse files
authored
Rollup merge of rust-lang#57337 - alexcrichton:prioritize-another, r=fitzgen
rustc: Place wasm linker args first instead of last This ensures that arguments passed via `-C link-arg` can override the first ones on the command line, for example allowing configuring of the stack size.
2 parents ca1e379 + ae1a50d commit a53a79f

File tree

1 file changed

+62
-60
lines changed

1 file changed

+62
-60
lines changed

src/librustc_codegen_ssa/back/linker.rs

+62-60
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,7 @@ impl LinkerInfo {
8181
}
8282

8383
LinkerFlavor::Lld(LldFlavor::Wasm) => {
84-
Box::new(WasmLd {
85-
cmd,
86-
sess,
87-
info: self
88-
}) as Box<dyn Linker>
84+
Box::new(WasmLd::new(cmd, sess, self)) as Box<dyn Linker>
8985
}
9086
}
9187
}
@@ -876,6 +872,67 @@ pub struct WasmLd<'a> {
876872
info: &'a LinkerInfo,
877873
}
878874

875+
impl<'a> WasmLd<'a> {
876+
fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> {
877+
// There have been reports in the wild (rustwasm/wasm-bindgen#119) of
878+
// using threads causing weird hangs and bugs. Disable it entirely as
879+
// this isn't yet the bottleneck of compilation at all anyway.
880+
cmd.arg("--no-threads");
881+
882+
// By default LLD only gives us one page of stack (64k) which is a
883+
// little small. Default to a larger stack closer to other PC platforms
884+
// (1MB) and users can always inject their own link-args to override this.
885+
cmd.arg("-z").arg("stack-size=1048576");
886+
887+
// By default LLD's memory layout is:
888+
//
889+
// 1. First, a blank page
890+
// 2. Next, all static data
891+
// 3. Finally, the main stack (which grows down)
892+
//
893+
// This has the unfortunate consequence that on stack overflows you
894+
// corrupt static data and can cause some exceedingly weird bugs. To
895+
// help detect this a little sooner we instead request that the stack is
896+
// placed before static data.
897+
//
898+
// This means that we'll generate slightly larger binaries as references
899+
// to static data will take more bytes in the ULEB128 encoding, but
900+
// stack overflow will be guaranteed to trap as it underflows instead of
901+
// corrupting static data.
902+
cmd.arg("--stack-first");
903+
904+
// FIXME we probably shouldn't pass this but instead pass an explicit
905+
// whitelist of symbols we'll allow to be undefined. Unfortunately
906+
// though we can't handle symbols like `log10` that LLVM injects at a
907+
// super late date without actually parsing object files. For now let's
908+
// stick to this and hopefully fix it before stabilization happens.
909+
cmd.arg("--allow-undefined");
910+
911+
// For now we just never have an entry symbol
912+
cmd.arg("--no-entry");
913+
914+
// Make the default table accessible
915+
cmd.arg("--export-table");
916+
917+
// Rust code should never have warnings, and warnings are often
918+
// indicative of bugs, let's prevent them.
919+
cmd.arg("--fatal-warnings");
920+
921+
// The symbol visibility story is a bit in flux right now with LLD.
922+
// It's... not entirely clear to me what's going on, but this looks to
923+
// make everything work when `export_symbols` isn't otherwise called for
924+
// things like executables.
925+
cmd.arg("--export-dynamic");
926+
927+
// LLD only implements C++-like demangling, which doesn't match our own
928+
// mangling scheme. Tell LLD to not demangle anything and leave it up to
929+
// us to demangle these symbols later.
930+
cmd.arg("--no-demangle");
931+
932+
WasmLd { cmd, sess, info }
933+
}
934+
}
935+
879936
impl<'a> Linker for WasmLd<'a> {
880937
fn link_dylib(&mut self, lib: &str) {
881938
self.cmd.arg("-l").arg(lib);
@@ -982,61 +1039,6 @@ impl<'a> Linker for WasmLd<'a> {
9821039
}
9831040

9841041
fn finalize(&mut self) -> Command {
985-
// There have been reports in the wild (rustwasm/wasm-bindgen#119) of
986-
// using threads causing weird hangs and bugs. Disable it entirely as
987-
// this isn't yet the bottleneck of compilation at all anyway.
988-
self.cmd.arg("--no-threads");
989-
990-
// By default LLD only gives us one page of stack (64k) which is a
991-
// little small. Default to a larger stack closer to other PC platforms
992-
// (1MB) and users can always inject their own link-args to override this.
993-
self.cmd.arg("-z").arg("stack-size=1048576");
994-
995-
// By default LLD's memory layout is:
996-
//
997-
// 1. First, a blank page
998-
// 2. Next, all static data
999-
// 3. Finally, the main stack (which grows down)
1000-
//
1001-
// This has the unfortunate consequence that on stack overflows you
1002-
// corrupt static data and can cause some exceedingly weird bugs. To
1003-
// help detect this a little sooner we instead request that the stack is
1004-
// placed before static data.
1005-
//
1006-
// This means that we'll generate slightly larger binaries as references
1007-
// to static data will take more bytes in the ULEB128 encoding, but
1008-
// stack overflow will be guaranteed to trap as it underflows instead of
1009-
// corrupting static data.
1010-
self.cmd.arg("--stack-first");
1011-
1012-
// FIXME we probably shouldn't pass this but instead pass an explicit
1013-
// whitelist of symbols we'll allow to be undefined. Unfortunately
1014-
// though we can't handle symbols like `log10` that LLVM injects at a
1015-
// super late date without actually parsing object files. For now let's
1016-
// stick to this and hopefully fix it before stabilization happens.
1017-
self.cmd.arg("--allow-undefined");
1018-
1019-
// For now we just never have an entry symbol
1020-
self.cmd.arg("--no-entry");
1021-
1022-
// Make the default table accessible
1023-
self.cmd.arg("--export-table");
1024-
1025-
// Rust code should never have warnings, and warnings are often
1026-
// indicative of bugs, let's prevent them.
1027-
self.cmd.arg("--fatal-warnings");
1028-
1029-
// The symbol visibility story is a bit in flux right now with LLD.
1030-
// It's... not entirely clear to me what's going on, but this looks to
1031-
// make everything work when `export_symbols` isn't otherwise called for
1032-
// things like executables.
1033-
self.cmd.arg("--export-dynamic");
1034-
1035-
// LLD only implements C++-like demangling, which doesn't match our own
1036-
// mangling scheme. Tell LLD to not demangle anything and leave it up to
1037-
// us to demangle these symbols later.
1038-
self.cmd.arg("--no-demangle");
1039-
10401042
::std::mem::replace(&mut self.cmd, Command::new(""))
10411043
}
10421044

0 commit comments

Comments
 (0)