Limit symbols exported from proc macros

Only __rustc_proc_macro_decls_*__ and rust_metadata_* need to be
exported for proc macros to work. All other symbols only increase binary
size and have the potential to conflict with symbols from the host
compiler.
This commit is contained in:
bjorn3 2022-07-30 12:16:33 +00:00
parent 760d8a2cb1
commit 6098e795a2
4 changed files with 36 additions and 6 deletions

View File

@ -656,9 +656,7 @@ impl<'a> Linker for GccLinker<'a> {
return;
}
if crate_type == CrateType::ProcMacro {
return;
}
// FIXME hide #[no_mangle] symbols for proc-macros
let is_windows = self.sess.target.is_like_windows;
let path = tmpdir.join(if is_windows { "list.def" } else { "list" });

View File

@ -257,16 +257,18 @@ fn exported_symbols_provider_local<'tcx>(
}));
}
if tcx.sess.crate_types().contains(&CrateType::Dylib) {
if tcx.sess.crate_types().contains(&CrateType::Dylib)
|| tcx.sess.crate_types().contains(&CrateType::ProcMacro)
{
let symbol_name = metadata_symbol_name(tcx);
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
symbols.push((
exported_symbol,
SymbolExportInfo {
level: SymbolExportLevel::Rust,
level: SymbolExportLevel::C,
kind: SymbolExportKind::Data,
used: false,
used: true,
},
));
}

View File

@ -5,6 +5,7 @@ include ../tools.mk
NM=nm -D
CDYLIB_NAME=liba_cdylib.so
RDYLIB_NAME=liba_rust_dylib.so
PROC_MACRO_NAME=liba_proc_macro.so
EXE_NAME=an_executable
COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.so
@ -12,6 +13,7 @@ ifeq ($(UNAME),Darwin)
NM=nm -gU
CDYLIB_NAME=liba_cdylib.dylib
RDYLIB_NAME=liba_rust_dylib.dylib
PROC_MACRO_NAME=liba_proc_macro.dylib
EXE_NAME=an_executable
COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.dylib
endif
@ -20,6 +22,7 @@ ifdef IS_WINDOWS
NM=nm -g
CDYLIB_NAME=liba_cdylib.dll.a
RDYLIB_NAME=liba_rust_dylib.dll.a
PROC_MACRO_NAME=liba_proc_macro.dll
EXE_NAME=an_executable.exe
COMBINED_CDYLIB_NAME=libcombined_rlib_dylib.dll.a
endif
@ -31,6 +34,7 @@ all:
$(RUSTC) -Zshare-generics=no an_rlib.rs
$(RUSTC) -Zshare-generics=no a_cdylib.rs
$(RUSTC) -Zshare-generics=no a_rust_dylib.rs
$(RUSTC) -Zshare-generics=no a_proc_macro.rs
$(RUSTC) -Zshare-generics=no an_executable.rs
$(RUSTC) -Zshare-generics=no a_cdylib.rs --crate-name combined_rlib_dylib --crate-type=rlib,cdylib
@ -54,6 +58,14 @@ all:
# Check that a Rust dylib does not export generics if -Zshare-generics=no
[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_generic_function_from_rlib)" -eq "0" ]
# Check that a proc macro exports its public #[no_mangle] functions
# FIXME avoid exporting #[no_mangle] symbols for proc macros
[ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_cdylib)" -eq "1" ]
# Check that a proc macro exports the public #[no_mangle] functions of dependencies
[ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ]
# Check that a proc macro DOES NOT export any public Rust functions
[ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ]
# FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032
ifndef IS_WINDOWS
# Check that an executable does not export any dynamic symbols
@ -75,6 +87,7 @@ endif
$(RUSTC) -Zshare-generics=yes an_rlib.rs
$(RUSTC) -Zshare-generics=yes a_cdylib.rs
$(RUSTC) -Zshare-generics=yes a_rust_dylib.rs
$(RUSTC) -Zshare-generics=yes a_proc_macro.rs
$(RUSTC) -Zshare-generics=yes an_executable.rs
# Check that a cdylib exports its public #[no_mangle] functions
@ -94,6 +107,14 @@ endif
[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_rust_function_from_rlib)" -eq "1" ]
[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_generic_function_from_rlib)" -eq "1" ]
# Check that a proc macro exports its public #[no_mangle] functions
# FIXME avoid exporting #[no_mangle] symbols for proc macros
[ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_cdylib)" -eq "1" ]
# Check that a proc macro exports the public #[no_mangle] functions of dependencies
[ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "1" ]
# Check that a proc macro DOES NOT export any public Rust functions
[ "$$($(NM) $(TMPDIR)/$(CDYLIB_NAME) | grep -v __imp_ | grep -c $(RE_ANY_RUST_SYMBOL))" -eq "0" ]
ifndef IS_WINDOWS
# Check that an executable does not export any dynamic symbols
[ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "0" ]

View File

@ -0,0 +1,9 @@
#![crate_type = "proc-macro"]
extern crate an_rlib;
// This should not be exported
#[no_mangle]
extern "C" fn public_c_function_from_cdylib() {
an_rlib::public_c_function_from_rlib();
}