Skip to content

Commit a946c1e

Browse files
committed
Auto merge of #114470 - pnkfelix:dont-export-no-mangle-from-proc-macros-issue-99978, r=bjorn3
Restrict linker version script of proc-macro crates to just its two symbols Restrict linker version script of proc-macro crates to just the two symbols of each proc-macro crate. The main known effect of doing this is to stop including `#[no_mangle]` symbols in the linker version script. Background: The combination of a proc-macro crate with an import of another crate that itself exports a no_mangle function was broken for a period of time, because: * In PR #99944 we stopped exporting no_mangle symbols from proc-macro crates; proc-macro crates have a very limited interface and are meant to be treated as a blackbox to everything except rustc itself. However: he constructed linker version script still referred to them, but resolving that discrepancy was left as a FIXME in the code, tagged with issue #99978. * In PR #108017 we started telling the linker to check (via the`--no-undefined-version` linker invocation flag) that every symbol referenced in the "linker version script" is provided as linker input. So the unresolved discrepancy from #99978 started surfacing as a compile-time error (e.g. #111888). Fix #111888 Fix #99978.
2 parents e3590fc + a2a7f27 commit a946c1e

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::{env, mem, str};
1313
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
1414
use rustc_metadata::find_native_static_library;
1515
use rustc_middle::middle::dependency_format::Linkage;
16+
use rustc_middle::middle::exported_symbols;
1617
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
1718
use rustc_middle::ty::TyCtxt;
1819
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
@@ -659,8 +660,6 @@ impl<'a> Linker for GccLinker<'a> {
659660
return;
660661
}
661662

662-
// FIXME(#99978) hide #[no_mangle] symbols for proc-macros
663-
664663
let is_windows = self.sess.target.is_like_windows;
665664
let path = tmpdir.join(if is_windows { "list.def" } else { "list" });
666665

@@ -1679,8 +1678,15 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
16791678
return exports.iter().map(ToString::to_string).collect();
16801679
}
16811680

1682-
let mut symbols = Vec::new();
1681+
if let CrateType::ProcMacro = crate_type {
1682+
exported_symbols_for_proc_macro_crate(tcx)
1683+
} else {
1684+
exported_symbols_for_non_proc_macro(tcx, crate_type)
1685+
}
1686+
}
16831687

1688+
fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
1689+
let mut symbols = Vec::new();
16841690
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
16851691
for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
16861692
if info.level.is_below_threshold(export_threshold) {
@@ -1691,6 +1697,19 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
16911697
symbols
16921698
}
16931699

1700+
fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
1701+
// `exported_symbols` will be empty when !should_codegen.
1702+
if !tcx.sess.opts.output_types.should_codegen() {
1703+
return Vec::new();
1704+
}
1705+
1706+
let stable_crate_id = tcx.sess.local_stable_crate_id();
1707+
let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
1708+
let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
1709+
1710+
vec![proc_macro_decls_name, metadata_symbol_name]
1711+
}
1712+
16941713
pub(crate) fn linked_symbols(
16951714
tcx: TyCtxt<'_>,
16961715
crate_type: CrateType,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
#![crate_type="lib"]
4+
5+
// Issue 111888: this crate (1.) is imported by a proc-macro crate and (2.)
6+
// exports a no_mangle function; that combination of acts was broken for some
7+
// period of time. See further discussion in the test file that imports this
8+
// crate.
9+
10+
#[no_mangle]
11+
pub fn some_no_mangle_function() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// build-pass
2+
// force-host
3+
// no-prefer-dynamic
4+
// aux-build:exports_no_mangle.rs
5+
#![crate_type = "proc-macro"]
6+
7+
// Issue #111888: this proc-macro crate imports another crate that itself
8+
// exports a no_mangle function.
9+
//
10+
// That combination was broken for a period of time, because:
11+
//
12+
// In PR #99944 we *stopped* exporting no_mangle symbols from
13+
// proc-macro crates. The constructed linker version script still referred
14+
// to them, but resolving that discrepancy was left as a FIXME in the code.
15+
//
16+
// In PR #108017 we started telling the linker to check (via the
17+
// `--no-undefined-version` linker invocation flag) that every symbol referenced
18+
// in the "linker version script" is actually present in the linker input. So
19+
// the unresolved discrepancy from #99944 started surfacing as a compile-time
20+
// error.
21+
22+
extern crate exports_no_mangle;

0 commit comments

Comments
 (0)