diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2018-06-01 10:20:00 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2018-07-10 13:43:01 -0700 |
| commit | 42eb85002ae4bda9899216805d03fa7d77279ede (patch) | |
| tree | 9168dbe500ecdfa86151701e15284c6c9f78d715 /src/librustc_codegen_llvm/back | |
| parent | c30acc7187fe5ab9ca8a34411bb89bfe241a0662 (diff) | |
| download | rust-42eb85002ae4bda9899216805d03fa7d77279ede.tar.gz rust-42eb85002ae4bda9899216805d03fa7d77279ede.zip | |
Upgrade to LLVM's master branch (LLVM 7)
This commit upgrades the main LLVM submodule to LLVM's current master branch. The LLD submodule is updated in tandem as well as compiler-builtins. Along the way support was also added for LLVM 7's new features. This primarily includes the support for custom section concatenation natively in LLD so we now add wasm custom sections in LLVM IR rather than having custom support in rustc itself for doing so. Some other miscellaneous changes are: * We now pass `--gc-sections` to `wasm-ld` * The optimization level is now passed to `wasm-ld` * A `--stack-first` option is passed to LLD to have stack overflow always cause a trap instead of corrupting static data * The wasm target for LLVM switched to `wasm32-unknown-unknown`. * The syntax for aligned pointers has changed in LLVM IR and tests are updated to reflect this. * The `thumbv6m-none-eabi` target is disabled due to an [LLVM bug][llbug] Nowadays we've been mostly only upgrading whenever there's a major release of LLVM but enough changes have been happening on the wasm target that there's been growing motivation for quite some time now to upgrade out version of LLD. To upgrade LLD, however, we need to upgrade LLVM to avoid needing to build yet another version of LLVM on the builders. The revision of LLVM in use here is arbitrarily chosen. We will likely need to continue to update it over time if and when we discover bugs. Once LLVM 7 is fully released we can switch to that channel as well. [llbug]: https://bugs.llvm.org/show_bug.cgi?id=37382
Diffstat (limited to 'src/librustc_codegen_llvm/back')
| -rw-r--r-- | src/librustc_codegen_llvm/back/link.rs | 6 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/back/linker.rs | 37 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/back/wasm.rs | 42 |
3 files changed, 38 insertions, 47 deletions
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 70053cb7e9d..e8636b1c999 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -29,7 +29,7 @@ use rustc::util::common::time; use rustc::util::fs::fix_windows_verbatim_for_gcc; use rustc::hir::def_id::CrateNum; use tempfile::{Builder as TempFileBuilder, TempDir}; -use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor, TargetTriple}; +use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor}; use rustc_data_structures::fx::FxHashSet; use context::get_reloc_model; use llvm; @@ -837,10 +837,8 @@ fn link_natively(sess: &Session, } } - if sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown") { + if sess.opts.target_triple.triple() == "wasm32-unknown-unknown" { wasm::rewrite_imports(&out_filename, &codegen_results.crate_info.wasm_imports); - wasm::add_custom_sections(&out_filename, - &codegen_results.crate_info.wasm_custom_sections); } } diff --git a/src/librustc_codegen_llvm/back/linker.rs b/src/librustc_codegen_llvm/back/linker.rs index 99249255d27..f07c758807e 100644 --- a/src/librustc_codegen_llvm/back/linker.rs +++ b/src/librustc_codegen_llvm/back/linker.rs @@ -86,6 +86,7 @@ impl LinkerInfo { LinkerFlavor::Lld(LldFlavor::Wasm) => { Box::new(WasmLd { cmd, + sess, }) as Box<Linker> } } @@ -919,11 +920,12 @@ fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> { symbols } -pub struct WasmLd { +pub struct WasmLd<'a> { cmd: Command, + sess: &'a Session, } -impl Linker for WasmLd { +impl<'a> Linker for WasmLd<'a> { fn link_dylib(&mut self, lib: &str) { self.cmd.arg("-l").arg(lib); } @@ -988,9 +990,20 @@ impl Linker for WasmLd { } fn gc_sections(&mut self, _keep_metadata: bool) { + self.cmd.arg("--gc-sections"); } fn optimize(&mut self) { + self.cmd.arg(match self.sess.opts.optimize { + OptLevel::No => "-O0", + OptLevel::Less => "-O1", + OptLevel::Default => "-O2", + OptLevel::Aggressive => "-O3", + // Currently LLD doesn't support `Os` and `Oz`, so pass through `O2` + // instead. + OptLevel::Size => "-O2", + OptLevel::SizeMin => "-O2" + }); } fn pgo_gen(&mut self) { @@ -1020,8 +1033,28 @@ impl Linker for WasmLd { // this isn't yet the bottleneck of compilation at all anyway. self.cmd.arg("--no-threads"); + // By default LLD only gives us one page of stack (64k) which is a + // little small. Default to a larger stack closer to other PC platforms + // (1MB) and users can always inject their own link-args to override this. self.cmd.arg("-z").arg("stack-size=1048576"); + // By default LLD's memory layout is: + // + // 1. First, a blank page + // 2. Next, all static data + // 3. Finally, the main stack (which grows down) + // + // This has the unfortunate consequence that on stack overflows you + // corrupt static data and can cause some exceedingly weird bugs. To + // help detect this a little sooner we instead request that the stack is + // placed before static data. + // + // This means that we'll generate slightly larger binaries as references + // to static data will take more bytes in the ULEB128 encoding, but + // stack overflow will be guaranteed to trap as it underflows instead of + // corrupting static data. + self.cmd.arg("--stack-first"); + // FIXME we probably shouldn't pass this but instead pass an explicit // whitelist of symbols we'll allow to be undefined. Unfortunately // though we can't handle symbols like `log10` that LLVM injects at a diff --git a/src/librustc_codegen_llvm/back/wasm.rs b/src/librustc_codegen_llvm/back/wasm.rs index c553eca08e6..d378d5af1c0 100644 --- a/src/librustc_codegen_llvm/back/wasm.rs +++ b/src/librustc_codegen_llvm/back/wasm.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::collections::BTreeMap; use std::fs; use std::path::Path; use std::str; @@ -24,45 +23,6 @@ const WASM_EXTERNAL_KIND_TABLE: u8 = 1; const WASM_EXTERNAL_KIND_MEMORY: u8 = 2; const WASM_EXTERNAL_KIND_GLOBAL: u8 = 3; -/// Append all the custom sections listed in `sections` to the wasm binary -/// specified at `path`. -/// -/// LLVM 6 which we're using right now doesn't have the ability to create custom -/// sections in wasm files nor does LLD have the ability to merge these sections -/// into one larger section when linking. It's expected that this will -/// eventually get implemented, however! -/// -/// Until that time though this is a custom implementation in rustc to append -/// all sections to a wasm file to the finished product that LLD produces. -/// -/// Support for this is landing in LLVM in https://reviews.llvm.org/D43097, -/// although after that support will need to be in LLD as well. -pub fn add_custom_sections(path: &Path, sections: &BTreeMap<String, Vec<u8>>) { - if sections.len() == 0 { - return - } - - let wasm = fs::read(path).expect("failed to read wasm output"); - - // see https://webassembly.github.io/spec/core/binary/modules.html#custom-section - let mut wasm = WasmEncoder { data: wasm }; - for (section, bytes) in sections { - // write the `id` identifier, 0 for a custom section - wasm.byte(0); - - // figure out how long our name descriptor will be - let mut name = WasmEncoder::new(); - name.str(section); - - // write the length of the payload followed by all its contents - wasm.u32((bytes.len() + name.data.len()) as u32); - wasm.data.extend_from_slice(&name.data); - wasm.data.extend_from_slice(bytes); - } - - fs::write(path, &wasm.data).expect("failed to write wasm output"); -} - /// Rewrite the module imports are listed from in a wasm module given the field /// name to module name mapping in `import_map`. /// @@ -80,7 +40,7 @@ pub fn add_custom_sections(path: &Path, sections: &BTreeMap<String, Vec<u8>>) { /// /// Support for this was added to LLVM in /// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still -/// needs to be added (AFAIK at the time of this writing) to LLD +/// needs to be added, tracked at https://bugs.llvm.org/show_bug.cgi?id=37168 pub fn rewrite_imports(path: &Path, import_map: &FxHashMap<String, String>) { if import_map.len() == 0 { return |
