diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index b2d28cef89976..3f6b45239bc95 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -39,6 +39,24 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool { } } +fn get_llvm_preserved_symbols() -> Vec { + let mut len = 0; + unsafe { + let symbols = llvm::LLVMRustPreservedSymbols(&mut len); + let symbols: &[*const _] = slice::from_raw_parts(symbols, len); + symbols + .iter() + .filter_map(|&symbol| { + if symbol.is_null() { + None + } else { + Some(String::from_utf8(CStr::from_ptr(symbol).to_bytes().to_vec()).unwrap()) + } + }) + .collect() + } +} + fn prepare_lto( cgcx: &CodegenContext, diag_handler: &Handler, @@ -53,8 +71,13 @@ fn prepare_lto( Lto::No => panic!("didn't request LTO but we're doing LTO"), }; + let llvm_reserved_symbols = get_llvm_preserved_symbols(); + let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| { - if info.level.is_below_threshold(export_threshold) || info.used { + if info.level.is_below_threshold(export_threshold) + || info.used + || llvm_reserved_symbols.contains(name) + { Some(CString::new(name.as_str()).unwrap()) } else { None diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 1bc5a435ded87..2b6d9bea84ce3 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2170,6 +2170,7 @@ extern "C" { pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char); pub fn LLVMRustPrintPasses(); pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char); + pub fn LLVMRustPreservedSymbols(len: *mut usize) -> *const *const c_char; pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t); pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>; diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index f4f3a35ca3833..e0447718e6303 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1043,6 +1043,20 @@ extern "C" void LLVMRustPrintPasses() { PB.printPassNames(outs()); } +// from /~https://github.com/llvm/llvm-project/blob/7021182d6b43de9488ab70de626192ce70b3a4a6/llvm/lib/Object/IRSymtab.cpp#L48-L57 +static const char *PreservedSymbols[] = { +#define HANDLE_LIBCALL(code, name) name, +#include "llvm/IR/RuntimeLibcalls.def" +#undef HANDLE_LIBCALL + "__ssp_canary_word", + "__stack_chk_guard", +}; + +extern "C" const char **LLVMRustPreservedSymbols(size_t *len) { + *len = sizeof(PreservedSymbols) / sizeof(PreservedSymbols[0]); + return PreservedSymbols; +} + extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols, size_t Len) { auto PreserveFunctions = [=](const GlobalValue &GV) { diff --git a/tests/run-make/wasm-spurious-import/Makefile b/tests/run-make/wasm-builtins-import/Makefile similarity index 100% rename from tests/run-make/wasm-spurious-import/Makefile rename to tests/run-make/wasm-builtins-import/Makefile diff --git a/tests/run-make/wasm-spurious-import/main.rs b/tests/run-make/wasm-builtins-import/main.rs similarity index 65% rename from tests/run-make/wasm-spurious-import/main.rs rename to tests/run-make/wasm-builtins-import/main.rs index fcbead5e28bd2..d7dbbe32ca4d2 100644 --- a/tests/run-make/wasm-spurious-import/main.rs +++ b/tests/run-make/wasm-builtins-import/main.rs @@ -8,7 +8,7 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! { #[no_mangle] pub fn multer(a: i128, b: i128) -> i128 { - // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported - // panic function in case of a bug. We verify that no imports exist in our verifier. + // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported function + // such as panic or __multi3 in case of a bug. We verify that no imports exist in our verifier. a * b } diff --git a/tests/run-make/wasm-spurious-import/verify.js b/tests/run-make/wasm-builtins-import/verify.js similarity index 100% rename from tests/run-make/wasm-spurious-import/verify.js rename to tests/run-make/wasm-builtins-import/verify.js