Skip to content

Commit f7751fa

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 c1ec76c commit f7751fa

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
@@ -39,6 +39,24 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
3939
}
4040
}
4141

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

74+
let llvm_reserved_symbols = get_llvm_preserved_symbols();
75+
5676
let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| {
57-
if info.level.is_below_threshold(export_threshold) || info.used {
77+
if info.level.is_below_threshold(export_threshold)
78+
|| info.used
79+
|| llvm_reserved_symbols.contains(name)
80+
{
5881
Some(CString::new(name.as_str()).unwrap())
5982
} else {
6083
None

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,7 @@ extern "C" {
21702170
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
21712171
pub fn LLVMRustPrintPasses();
21722172
pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
2173+
pub fn LLVMRustPreservedSymbols(len: *mut usize) -> *const *const c_char;
21732174
pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t);
21742175

21752176
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
@@ -1043,6 +1043,20 @@ extern "C" void LLVMRustPrintPasses() {
10431043
PB.printPassNames(outs());
10441044
}
10451045

1046+
// from https://github.com/llvm/llvm-project/blob/7021182d6b43de9488ab70de626192ce70b3a4a6/llvm/lib/Object/IRSymtab.cpp#L48-L57
1047+
static const char *PreservedSymbols[] = {
1048+
#define HANDLE_LIBCALL(code, name) name,
1049+
#include "llvm/IR/RuntimeLibcalls.def"
1050+
#undef HANDLE_LIBCALL
1051+
"__ssp_canary_word",
1052+
"__stack_chk_guard",
1053+
};
1054+
1055+
extern "C" const char **LLVMRustPreservedSymbols(size_t *len) {
1056+
*len = sizeof(PreservedSymbols) / sizeof(PreservedSymbols[0]);
1057+
return PreservedSymbols;
1058+
}
1059+
10461060
extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
10471061
size_t Len) {
10481062
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)