Skip to content

Commit a120caf

Browse files
committed
rustc: Update wasm32 support for LLVM 9
This commit brings in a number of minor updates for rustc's support for the wasm target which has changed in the LLVM 9 update. Notable updates include: * The compiler now no longer manually inserts the `producers` section, instead relying on LLVM to do so. LLVM uses the `llvm.ident` metadata for the `processed-by` directive (which is now emitted on the wasm target in this PR) and it uses debuginfo to figure out what `language` to put in the `producers` section. * Threaded WebAssembly code now requires different flags to be passed with LLD. In LLD we now pass: * `--shared-memory` - required since objects are compiled with atomics. This also means that the generated memory will be marked as `shared`. * `--max-memory=1GB` - required with the `--shared-memory` argument since shared memories in WebAssembly must have a maximum size. The 1GB number is intended to be a conservative estimate for rustc, but it should be overridable with `-C link-arg` if necessary. * `--passive-segments` - this has become the default for multithreaded memory, but when compiling a threaded module all data segments need to be marked as passive to ensure they don't re-initialize memory for each thread. This will also cause LLD to emit a synthetic function to initialize memory which users will have to arrange to call. * The `__heap_base` and `__data_end` globals are explicitly exported since they're now hidden by default due to the `--export` flags we pass to LLD.
1 parent eedf6ce commit a120caf

File tree

5 files changed

+59
-203
lines changed

5 files changed

+59
-203
lines changed

src/librustc_codegen_llvm/debuginfo/metadata.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -913,9 +913,12 @@ pub fn compile_unit_metadata(
913913
}
914914

915915
debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
916+
let rustc_producer = format!(
917+
"rustc version {}",
918+
option_env!("CFG_VERSION").expect("CFG_VERSION"),
919+
);
916920
// FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
917-
let producer = format!("clang LLVM (rustc version {})",
918-
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
921+
let producer = format!("clang LLVM ({})", rustc_producer);
919922

920923
let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
921924
let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo);
@@ -980,6 +983,21 @@ pub fn compile_unit_metadata(
980983
gcov_metadata);
981984
}
982985

986+
// Insert `llvm.ident` metadata on the wasm32 targets since that will
987+
// get hooked up to the "producer" sections `processed-by` information.
988+
if tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
989+
let name_metadata = llvm::LLVMMDStringInContext(
990+
debug_context.llcontext,
991+
rustc_producer.as_ptr() as *const _,
992+
rustc_producer.as_bytes().len() as c_uint,
993+
);
994+
llvm::LLVMAddNamedMetadataOperand(
995+
debug_context.llmod,
996+
const_cstr!("llvm.ident").as_ptr(),
997+
llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1),
998+
);
999+
}
1000+
9831001
return unit_metadata;
9841002
};
9851003

src/librustc_codegen_ssa/back/link.rs

-8
Original file line numberDiff line numberDiff line change
@@ -678,14 +678,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
678678
sess.fatal(&format!("failed to run dsymutil: {}", e))
679679
}
680680
}
681-
682-
if sess.opts.target_triple.triple() == "wasm32-unknown-unknown" {
683-
super::wasm::add_producer_section(
684-
&out_filename,
685-
&sess.edition().to_string(),
686-
option_env!("CFG_VERSION").unwrap_or("unknown"),
687-
);
688-
}
689681
}
690682

691683
/// Returns a boolean indicating whether the specified crate should be ignored

src/librustc_codegen_ssa/back/linker.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,38 @@ pub struct WasmLd<'a> {
881881
}
882882

883883
impl<'a> WasmLd<'a> {
884-
fn new(cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> {
884+
fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> {
885+
// If the atomics feature is enabled for wasm then we need a whole bunch
886+
// of flags:
887+
//
888+
// * `--shared-memory` - the link won't even succeed without this, flags
889+
// the one linear memory as `shared`
890+
//
891+
// * `--max-memory=1G` - when specifying a shared memory this must also
892+
// be specified. We conservatively choose 1GB but users should be able
893+
// to override this with `-C link-arg`.
894+
//
895+
// * `--import-memory` - it doesn't make much sense for memory to be
896+
// exported in a threaded module because typically you're
897+
// sharing memory and instantiating the module multiple times. As a
898+
// result if it were exported then we'd just have no sharing.
899+
//
900+
// * `--passive-segments` - all memory segments should be passive to
901+
// prevent each module instantiation from reinitializing memory.
902+
//
903+
// * `--export=__wasm_init_memory` - when using `--passive-segments` the
904+
// linker will synthesize this function, and so we need to make sure
905+
// that our usage of `--export` below won't accidentally cause this
906+
// function to get deleted.
907+
let atomics = sess.opts.cg.target_feature.contains("+atomics") ||
908+
sess.target.target.options.features.contains("+atomics");
909+
if atomics {
910+
cmd.arg("--shared-memory");
911+
cmd.arg("--max-memory=1073741824");
912+
cmd.arg("--import-memory");
913+
cmd.arg("--passive-segments");
914+
cmd.arg("--export=__wasm_init_memory");
915+
}
885916
WasmLd { cmd, sess, info }
886917
}
887918
}
@@ -984,6 +1015,13 @@ impl<'a> Linker for WasmLd<'a> {
9841015
for sym in self.info.exports[&crate_type].iter() {
9851016
self.cmd.arg("--export").arg(&sym);
9861017
}
1018+
1019+
// LLD will hide these otherwise-internal symbols since our `--export`
1020+
// list above is a whitelist of what to export. Various bits and pieces
1021+
// of tooling use this, so be sure these symbols make their way out of
1022+
// the linker as well.
1023+
self.cmd.arg("--export=__heap_base");
1024+
self.cmd.arg("--export=__data_end");
9871025
}
9881026

9891027
fn subsystem(&mut self, _subsystem: &str) {

src/librustc_codegen_ssa/back/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,3 @@ pub mod command;
66
pub mod symbol_export;
77
pub mod archive;
88
pub mod rpath;
9-
pub mod wasm;

src/librustc_codegen_ssa/back/wasm.rs

-191
This file was deleted.

0 commit comments

Comments
 (0)