From 6674c94d15e8bdf2d6d3d53d73acb28bd0b10c36 Mon Sep 17 00:00:00 2001 From: csmoe Date: Mon, 25 Jul 2022 05:20:23 +0000 Subject: [PATCH] feat: impl export-executable-symbols --- compiler/rustc_codegen_ssa/src/back/link.rs | 7 ++++++- compiler/rustc_codegen_ssa/src/back/linker.rs | 17 +++++++++++++---- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/src/options.rs | 2 ++ .../run-make/export-executable-symbols/Makefile | 11 +++++++++++ .../run-make/export-executable-symbols/main.rs | 8 ++++++++ src/test/rustdoc-ui/z-help.stdout | 1 + 7 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 src/test/run-make/export-executable-symbols/Makefile create mode 100644 src/test/run-make/export-executable-symbols/main.rs diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 878a670cba3ef..48d24ecf41280 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2082,7 +2082,12 @@ fn add_order_independent_options( // sections to ensure we have all the data for PGO. let keep_metadata = crate_type == CrateType::Dylib || sess.opts.cg.profile_generate.enabled(); - cmd.gc_sections(keep_metadata); + if crate_type != CrateType::Executable || !sess.opts.unstable_opts.export_executable_symbols + { + cmd.gc_sections(keep_metadata); + } else { + cmd.no_gc_sections(); + } } cmd.set_output_kind(link_output_kind, out_filename); diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index d4a9db4af23a2..8e5ac9da4ac50 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -640,9 +640,14 @@ impl<'a> Linker for GccLinker<'a> { fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) { // Symbol visibility in object files typically takes care of this. - if crate_type == CrateType::Executable && self.sess.target.override_export_symbols.is_none() - { - return; + if crate_type == CrateType::Executable { + let should_export_executable_symbols = + self.sess.opts.unstable_opts.export_executable_symbols; + if self.sess.target.override_export_symbols.is_none() + && !should_export_executable_symbols + { + return; + } } // We manually create a list of exported symbols to ensure we don't expose any more. @@ -969,7 +974,11 @@ impl<'a> Linker for MsvcLinker<'a> { fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) { // Symbol visibility takes care of this typically if crate_type == CrateType::Executable { - return; + let should_export_executable_symbols = + self.sess.opts.unstable_opts.export_executable_symbols; + if !should_export_executable_symbols { + return; + } } let path = tmpdir.join("lib.def"); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d07e17f679251..0a0eb99cd9266 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -733,6 +733,7 @@ fn test_unstable_options_tracking_hash() { tracked!(debug_macros, true); tracked!(dep_info_omit_d_target, true); tracked!(drop_tracking, true); + tracked!(export_executable_symbols, true); tracked!(dual_proc_macros, true); tracked!(dwarf_version, Some(5)); tracked!(emit_thin_lto, false); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 1b583417ca089..28e2e0db89a1f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1282,6 +1282,8 @@ options! { "emit a section containing stack size metadata (default: no)"), emit_thin_lto: bool = (true, parse_bool, [TRACKED], "emit the bc module with thin LTO info (default: yes)"), + export_executable_symbols: bool = (false, parse_bool, [TRACKED], + "export symbols from executables, as if they were dynamic libraries"), fewer_names: Option = (None, parse_opt_bool, [TRACKED], "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ (default: no)"), diff --git a/src/test/run-make/export-executable-symbols/Makefile b/src/test/run-make/export-executable-symbols/Makefile new file mode 100644 index 0000000000000..5006f9cb8cfea --- /dev/null +++ b/src/test/run-make/export-executable-symbols/Makefile @@ -0,0 +1,11 @@ +-include ../../run-make-fulldeps/tools.mk + +# ignore-wasm32 +# ignore-wasm64 +# ignore-none no-std is not supported +# only-linux + +all: + $(RUSTC) -Zexport-executable-symbols main.rs --target $(TARGET) --crate-type=bin + nm $(TMPDIR)/main | $(CGREP) exported_symbol + diff --git a/src/test/run-make/export-executable-symbols/main.rs b/src/test/run-make/export-executable-symbols/main.rs new file mode 100644 index 0000000000000..c498381a33f64 --- /dev/null +++ b/src/test/run-make/export-executable-symbols/main.rs @@ -0,0 +1,8 @@ +// edition:2018 + +fn main() {} + +#[no_mangle] +pub fn exported_symbol() -> i8 { + 42 +} diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index bcf323e1cab89..86e42440bd0bc 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -37,6 +37,7 @@ -Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform) -Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no) -Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes) + -Z export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries -Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no) -Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no) -Z fuel=val -- set the optimization fuel quota for a crate