Skip to content

Commit 4df4d43

Browse files
committed
Add PreservedSymbols from LLVM to LTO.
When building with LTO, builtin functions that are defined but whose calls have not been inserted yet, get internalized. We need to prevent these symbols from being internalized at LTO time. Refer to https://reviews.llvm.org/D49434.
1 parent 7fa7f2d commit 4df4d43

File tree

6 files changed

+41
-3
lines changed

6 files changed

+41
-3
lines changed

compiler/rustc_codegen_llvm/src/back/lto.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,24 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
4141
}
4242
}
4343

44+
fn get_llvm_preserved_symbols() -> Vec<String> {
45+
let mut len = 0;
46+
unsafe {
47+
let symbols = llvm::LLVMRustPreservedSymbols(&mut len);
48+
let symbols: &[*const _] = slice::from_raw_parts(symbols, len);
49+
symbols
50+
.iter()
51+
.filter_map(|&symbol| {
52+
if symbol.is_null() {
53+
None
54+
} else {
55+
Some(String::from_utf8(CStr::from_ptr(symbol).to_bytes().to_vec()).unwrap())
56+
}
57+
})
58+
.collect()
59+
}
60+
}
61+
4462
fn prepare_lto(
4563
cgcx: &CodegenContext<LlvmCodegenBackend>,
4664
diag_handler: &Handler,
@@ -55,8 +73,13 @@ fn prepare_lto(
5573
Lto::No => panic!("didn't request LTO but we're doing LTO"),
5674
};
5775

76+
let llvm_reserved_symbols = get_llvm_preserved_symbols();
77+
5878
let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| {
59-
if info.level.is_below_threshold(export_threshold) || info.used {
79+
if info.level.is_below_threshold(export_threshold)
80+
|| info.used
81+
|| llvm_reserved_symbols.contains(name)
82+
{
6083
Some(CString::new(name.as_str()).unwrap())
6184
} else {
6285
None

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,7 @@ extern "C" {
21872187
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
21882188
pub fn LLVMRustPrintPasses();
21892189
pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
2190+
pub fn LLVMRustPreservedSymbols(len: *mut usize) -> *const *const c_char;
21902191
pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t);
21912192

21922193
pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,20 @@ extern "C" void LLVMRustPrintPasses() {
11201120
PB.printPassNames(outs());
11211121
}
11221122

1123+
// from https://github.com/llvm/llvm-project/blob/7021182d6b43de9488ab70de626192ce70b3a4a6/llvm/lib/Object/IRSymtab.cpp#L48-L57
1124+
static const char *PreservedSymbols[] = {
1125+
#define HANDLE_LIBCALL(code, name) name,
1126+
#include "llvm/IR/RuntimeLibcalls.def"
1127+
#undef HANDLE_LIBCALL
1128+
"__ssp_canary_word",
1129+
"__stack_chk_guard",
1130+
};
1131+
1132+
extern "C" const char **LLVMRustPreservedSymbols(size_t *len) {
1133+
*len = sizeof(PreservedSymbols) / sizeof(PreservedSymbols[0]);
1134+
return PreservedSymbols;
1135+
}
1136+
11231137
extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
11241138
size_t Len) {
11251139
auto PreserveFunctions = [=](const GlobalValue &GV) {

tests/run-make/wasm-spurious-import/main.rs renamed to tests/run-make/wasm-builtins-import/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! {
88

99
#[no_mangle]
1010
pub fn multer(a: i128, b: i128) -> i128 {
11-
// Trigger usage of the __multi3 compiler intrinsic which then leads to an imported
12-
// panic function in case of a bug. We verify that no imports exist in our verifier.
11+
// Trigger usage of the __multi3 compiler intrinsic which then leads to an imported function
12+
// such as panic or __multi3 in case of a bug. We verify that no imports exist in our verifier.
1313
a * b
1414
}

0 commit comments

Comments
 (0)