From 2850388abca6fce2d7ef4e3e1d4013726874c11c Mon Sep 17 00:00:00 2001 From: csmoe Date: Sun, 8 Aug 2021 18:22:31 +0800 Subject: [PATCH 1/2] add codegen flag export symbols from executable --- compiler/rustc_codegen_ssa/src/back/linker.rs | 13 +++++++++---- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/src/options.rs | 2 ++ src/test/run-make/export-executable-symbols/main.rs | 10 ++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 src/test/run-make/export-executable-symbols/main.rs diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 2c15ed831670c..17482a63ef73a 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -644,9 +644,12 @@ 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 { + if self.sess.target.override_export_symbols.is_none() + && !self.sess.opts.cg.export_executable_symbols + { + return; + } } // We manually create a list of exported symbols to ensure we don't expose any more. @@ -970,7 +973,9 @@ 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; + if !self.sess.opts.cg.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 fe75ee8b37b8d..a91c9f6b0d41b 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -573,6 +573,7 @@ fn test_codegen_options_tracking_hash() { tracked!(debug_assertions, Some(true)); tracked!(debuginfo, 0xdeadbeef); tracked!(embed_bitcode, false); + tracked!(export_executable_symbols, true); tracked!(force_frame_pointers, Some(false)); tracked!(force_unwind_tables, Some(true)); tracked!(inline_threshold, Some(0xf007ba11)); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 4994f8eaeb2dc..7af9304b25573 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1054,6 +1054,8 @@ options! { "allow the linker to link its default libraries (default: no)"), embed_bitcode: bool = (true, parse_bool, [TRACKED], "emit bitcode in rlibs (default: yes)"), + export_executable_symbols: bool = (false, parse_bool, [TRACKED], + "export symbols from executables, as if they were dynamic libraries"), extra_filename: String = (String::new(), parse_string, [UNTRACKED], "extra data to put in each output filename"), force_frame_pointers: Option = (None, parse_opt_bool, [TRACKED], 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..761bba2409b52 --- /dev/null +++ b/src/test/run-make/export-executable-symbols/main.rs @@ -0,0 +1,10 @@ +// edition:2018 + +fn main() { + foo(); +} + +#[no_mangle] +pub extern "C" fn foo() -> i32 { + 1 + 1 +} From 09b0c5562d07fce0c0621a2ebf9cb42a1f311ddf Mon Sep 17 00:00:00 2001 From: csmoe Date: Sun, 22 Aug 2021 21:29:38 +0800 Subject: [PATCH 2/2] add export executable symbols make run --- compiler/rustc_codegen_ssa/src/back/linker.rs | 4 +-- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/options.rs | 4 +-- .../export-executable-symbols/Makefile | 7 ++++ .../run-make/export-executable-symbols/foo.rs | 8 +++++ .../export-executable-symbols/main.rs | 33 +++++++++++++++++-- 6 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 src/test/run-make/export-executable-symbols/Makefile create mode 100644 src/test/run-make/export-executable-symbols/foo.rs diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 17482a63ef73a..18c2dcd888674 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -646,7 +646,7 @@ impl<'a> Linker for GccLinker<'a> { // Symbol visibility in object files typically takes care of this. if crate_type == CrateType::Executable { if self.sess.target.override_export_symbols.is_none() - && !self.sess.opts.cg.export_executable_symbols + && !self.sess.opts.debugging_opts.export_executable_symbols { return; } @@ -973,7 +973,7 @@ 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 { - if !self.sess.opts.cg.export_executable_symbols { + if !self.sess.opts.debugging_opts.export_executable_symbols { return; } } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index a91c9f6b0d41b..fc4df88b61acc 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -573,7 +573,6 @@ fn test_codegen_options_tracking_hash() { tracked!(debug_assertions, Some(true)); tracked!(debuginfo, 0xdeadbeef); tracked!(embed_bitcode, false); - tracked!(export_executable_symbols, true); tracked!(force_frame_pointers, Some(false)); tracked!(force_unwind_tables, Some(true)); tracked!(inline_threshold, Some(0xf007ba11)); @@ -735,6 +734,7 @@ fn test_debugging_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!(fewer_names, Some(true)); tracked!(force_unstable_if_unmarked, true); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 7af9304b25573..666e515632f02 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1054,8 +1054,6 @@ options! { "allow the linker to link its default libraries (default: no)"), embed_bitcode: bool = (true, parse_bool, [TRACKED], "emit bitcode in rlibs (default: yes)"), - export_executable_symbols: bool = (false, parse_bool, [TRACKED], - "export symbols from executables, as if they were dynamic libraries"), extra_filename: String = (String::new(), parse_string, [UNTRACKED], "extra data to put in each output filename"), force_frame_pointers: Option = (None, parse_opt_bool, [TRACKED], @@ -1244,6 +1242,8 @@ options! { an additional `.html` file showing the computed coverage spans."), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], "emit a section containing stack size metadata (default: no)"), + 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..2c720a8624683 --- /dev/null +++ b/src/test/run-make/export-executable-symbols/Makefile @@ -0,0 +1,7 @@ +-include ../../run-make-fulldeps/tools.mk + +all: + $(RUSTC) --crate-type=cdylib foo.rs + $(RUSTC) -Zexport-executable-symbols -lfoo -L "$(TMPDIR)" main.rs + $(call $(TMPDIR)/main) + diff --git a/src/test/run-make/export-executable-symbols/foo.rs b/src/test/run-make/export-executable-symbols/foo.rs new file mode 100644 index 0000000000000..4585fc5abead0 --- /dev/null +++ b/src/test/run-make/export-executable-symbols/foo.rs @@ -0,0 +1,8 @@ +extern "C" { + fn exported_symbol() -> i8; +} + +#[no_mangle] +pub extern "C" fn call_exported_symbol() -> i8 { + unsafe { exported_symbol() } +} diff --git a/src/test/run-make/export-executable-symbols/main.rs b/src/test/run-make/export-executable-symbols/main.rs index 761bba2409b52..6041648caab6b 100644 --- a/src/test/run-make/export-executable-symbols/main.rs +++ b/src/test/run-make/export-executable-symbols/main.rs @@ -1,10 +1,37 @@ // edition:2018 +#![feature(rustc_private)] + +extern crate libc; +use std::ffi::*; +use std::os::unix::ffi::*; + fn main() { - foo(); + let path = std::env::var("TMPDIR").unwrap(); + let path = std::path::PathBuf::from(path).join("libfoo.so"); + + let s = CString::new(path.as_os_str().as_bytes()).unwrap(); + let handle = unsafe { libc::dlopen(s.as_ptr(), libc::RTLD_LAZY | libc::RTLD_GLOBAL) }; + if handle.is_null() { + let msg = unsafe { CStr::from_ptr(libc::dlerror() as *const _) }; + panic!("failed to dlopen lib {:?}", msg); + } + + unsafe { + libc::dlerror(); + } + + let raw_string = CString::new("call_exported_symbol").unwrap(); + let symbol = unsafe { libc::dlsym(handle as *mut libc::c_void, raw_string.as_ptr()) }; + if symbol.is_null() { + let msg = unsafe { CStr::from_ptr(libc::dlerror() as *const _) }; + panic!("failed to load symbol {:?}", msg); + } + let func: extern "C" fn() -> i8 = unsafe { std::mem::transmute(symbol) }; + assert_eq!(func(), 42); } #[no_mangle] -pub extern "C" fn foo() -> i32 { - 1 + 1 +pub fn exported_symbol() -> i8 { + 42 }