about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2019-05-03 13:59:50 -0700
committerAlex Crichton <alex@alexcrichton.com>2019-05-03 14:09:01 -0700
commit884632cc796816fd9d3c8de60f2245c216f9a25a (patch)
tree6a77de2a110d0f5d0f2313c05c30756382d5c098
parent3af1bdc4bcc502d576b1e836f99bae1eb29dbafd (diff)
downloadrust-884632cc796816fd9d3c8de60f2245c216f9a25a.tar.gz
rust-884632cc796816fd9d3c8de60f2245c216f9a25a.zip
rustc: Always handle exported symbols on the wasm target
Currently when linking an artifact rustc will only conditionally call
the `Linker::export_symbols` function, but this causes issues on some
targets, like WebAssembly, where it means that executable outputs will
not have the same symbols exported that cdylib outputs have. This commit
sinks the conditional call to `export_symbols` inside the various
implementations of the function that still need it, and otherwise the
wasm linker is configured to always pass through symbol visibility
lists.
-rw-r--r--src/librustc_codegen_ssa/back/link.rs10
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs10
-rw-r--r--src/test/run-make/wasm-export-all-symbols/Makefile6
-rw-r--r--src/test/run-make/wasm-export-all-symbols/main.rs3
-rw-r--r--src/test/run-make/wasm-export-all-symbols/verify.js10
5 files changed, 31 insertions, 8 deletions
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index f25891d77ce..d530af559af 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -1017,12 +1017,10 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
         }
     }
 
-    // If we're building a dynamic library then some platforms need to make sure
-    // that all symbols are exported correctly from the dynamic library.
-    if crate_type != config::CrateType::Executable ||
-       sess.target.target.options.is_like_emscripten {
-        cmd.export_symbols(tmpdir, crate_type);
-    }
+    // If we're building something like a dynamic library then some platforms
+    // need to make sure that all symbols are exported correctly from the
+    // dynamic library.
+    cmd.export_symbols(tmpdir, crate_type);
 
     // When linking a dynamic library, we put the metadata into a section of the
     // executable. This metadata is in a separate object file from the main
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index c99fc17dd89..926f4febe7b 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -372,6 +372,11 @@ impl<'a> Linker for GccLinker<'a> {
     }
 
     fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
+        // Symbol visibility in object files typically takes care of this.
+        if crate_type == CrateType::Executable {
+            return;
+        }
+
         // If we're compiling a dylib, then we let symbol visibility in object
         // files to take care of whether they're exported or not.
         //
@@ -645,6 +650,11 @@ impl<'a> Linker for MsvcLinker<'a> {
     fn export_symbols(&mut self,
                       tmpdir: &Path,
                       crate_type: CrateType) {
+        // Symbol visibility takes care of this typically
+        if crate_type == CrateType::Executable {
+            return;
+        }
+
         let path = tmpdir.join("lib.def");
         let res: io::Result<()> = try {
             let mut f = BufWriter::new(File::create(&path)?);
diff --git a/src/test/run-make/wasm-export-all-symbols/Makefile b/src/test/run-make/wasm-export-all-symbols/Makefile
index 039481215f0..15403d8d410 100644
--- a/src/test/run-make/wasm-export-all-symbols/Makefile
+++ b/src/test/run-make/wasm-export-all-symbols/Makefile
@@ -6,8 +6,14 @@ all:
 	$(RUSTC) bar.rs --target wasm32-unknown-unknown
 	$(RUSTC) foo.rs --target wasm32-unknown-unknown
 	$(NODE) verify.js $(TMPDIR)/foo.wasm
+	$(RUSTC) main.rs --target wasm32-unknown-unknown
+	$(NODE) verify.js $(TMPDIR)/main.wasm
 	$(RUSTC) bar.rs --target wasm32-unknown-unknown -O
 	$(RUSTC) foo.rs --target wasm32-unknown-unknown -O
 	$(NODE) verify.js $(TMPDIR)/foo.wasm
+	$(RUSTC) main.rs --target wasm32-unknown-unknown -O
+	$(NODE) verify.js $(TMPDIR)/main.wasm
 	$(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto
 	$(NODE) verify.js $(TMPDIR)/foo.wasm
+	$(RUSTC) main.rs --target wasm32-unknown-unknown -C lto
+	$(NODE) verify.js $(TMPDIR)/main.wasm
diff --git a/src/test/run-make/wasm-export-all-symbols/main.rs b/src/test/run-make/wasm-export-all-symbols/main.rs
new file mode 100644
index 00000000000..0edda7d7b88
--- /dev/null
+++ b/src/test/run-make/wasm-export-all-symbols/main.rs
@@ -0,0 +1,3 @@
+extern crate bar;
+
+fn main() {}
diff --git a/src/test/run-make/wasm-export-all-symbols/verify.js b/src/test/run-make/wasm-export-all-symbols/verify.js
index 0f56fa45c22..7b6fc7a4568 100644
--- a/src/test/run-make/wasm-export-all-symbols/verify.js
+++ b/src/test/run-make/wasm-export-all-symbols/verify.js
@@ -16,7 +16,13 @@ for (const entry of list) {
   nexports += 1;
 }
 
-if (nexports != 1)
-  throw new Error("should only have one function export");
 if (my_exports.foo === undefined)
   throw new Error("`foo` wasn't defined");
+
+if (my_exports.main === undefined) {
+  if (nexports != 1)
+    throw new Error("should only have one function export");
+} else {
+  if (nexports != 2)
+    throw new Error("should only have two function exports");
+}