diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-04-14 00:39:44 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-04-14 00:39:44 +0200 |
| commit | 7ff376b3b27d2e5c5c01b336924bcc3e507e5c4d (patch) | |
| tree | 78ad46500c21bb3cad0f686c2ae348b115f39b93 /src/librustc_codegen_llvm/back | |
| parent | c4a3332d38c6c92394b5f7818f0a963fbcf86052 (diff) | |
| parent | 724ca0584e2be0714edf2f30b86230666d7a9d19 (diff) | |
| download | rust-7ff376b3b27d2e5c5c01b336924bcc3e507e5c4d.tar.gz rust-7ff376b3b27d2e5c5c01b336924bcc3e507e5c4d.zip | |
Rollup merge of #59812 - michaelwoerister:profile-gen-msvc-imp, r=alexcrichton
Exclude profiler-generated symbols from MSVC __imp_-symbol workaround. LLVM's profiling instrumentation adds a few symbols that are used by the profiler runtime. Since these show up as globals in the LLVM IR, the compiler generates `dllimport`-related `__imp_` stubs for them. This can lead to linker errors because the instrumentation symbols have weak linkage or are in a comdat section, but the `__imp_` stubs aren't. Instead of trying to replicate the linkage/comdat setup for the stubs, this PR just excludes the profiler-related symbols from stub-generation since they aren't supposed to be referenced via `__declspec(dllimport)` anywhere anyway. r? @alexcrichton EDIT: I considered making this more general, i.e. inferring from the symbol name if it is a Rust symbol or not. But then I figured out that that would yield false negatives for `#[no_mangle]` et al, so I went with a blacklist approach.
Diffstat (limited to 'src/librustc_codegen_llvm/back')
| -rw-r--r-- | src/librustc_codegen_llvm/back/write.rs | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 4d52df91a8d..3ae169a597a 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -793,6 +793,7 @@ fn create_msvc_imps( } else { "\x01__imp_" }; + unsafe { let i8p_ty = Type::i8p_llcx(llcx); let globals = base::iter_globals(llmod) @@ -800,14 +801,23 @@ fn create_msvc_imps( llvm::LLVMRustGetLinkage(val) == llvm::Linkage::ExternalLinkage && llvm::LLVMIsDeclaration(val) == 0 }) - .map(move |val| { + .filter_map(|val| { + // Exclude some symbols that we know are not Rust symbols. let name = CStr::from_ptr(llvm::LLVMGetValueName(val)); + if ignored(name.to_bytes()) { + None + } else { + Some((val, name)) + } + }) + .map(move |(val, name)| { let mut imp_name = prefix.as_bytes().to_vec(); imp_name.extend(name.to_bytes()); let imp_name = CString::new(imp_name).unwrap(); (imp_name, val) }) .collect::<Vec<_>>(); + for (imp_name, val) in globals { let imp = llvm::LLVMAddGlobal(llmod, i8p_ty, @@ -816,4 +826,10 @@ fn create_msvc_imps( llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage); } } + + // Use this function to exclude certain symbols from `__imp` generation. + fn ignored(symbol_name: &[u8]) -> bool { + // These are symbols generated by LLVM's profiling instrumentation + symbol_name.starts_with(b"__llvm_profile_") + } } |
