Skip to content

Commit 76f7332

Browse files
authored
Rollup merge of rust-lang#85673 - csmoe:export-exe-sym, r=bjorn3
RFC-2841: add codegen flag export symbols from executable Closes rust-lang#84161 r? ```@nikomatsakis``` ```@Mark-Simulacrum```
2 parents 4b133a7 + 6aa0984 commit 76f7332

File tree

6 files changed

+64
-4
lines changed

6 files changed

+64
-4
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -641,9 +641,12 @@ impl<'a> Linker for GccLinker<'a> {
641641

642642
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
643643
// Symbol visibility in object files typically takes care of this.
644-
if crate_type == CrateType::Executable && self.sess.target.override_export_symbols.is_none()
645-
{
646-
return;
644+
if crate_type == CrateType::Executable {
645+
if self.sess.target.override_export_symbols.is_none()
646+
&& !self.sess.opts.debugging_opts.export_executable_symbols
647+
{
648+
return;
649+
}
647650
}
648651

649652
// We manually create a list of exported symbols to ensure we don't expose any more.
@@ -963,7 +966,9 @@ impl<'a> Linker for MsvcLinker<'a> {
963966
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
964967
// Symbol visibility takes care of this typically
965968
if crate_type == CrateType::Executable {
966-
return;
969+
if !self.sess.opts.debugging_opts.export_executable_symbols {
970+
return;
971+
}
967972
}
968973

969974
let path = tmpdir.join("lib.def");

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ fn test_debugging_options_tracking_hash() {
733733
tracked!(debug_macros, true);
734734
tracked!(dep_info_omit_d_target, true);
735735
tracked!(drop_tracking, true);
736+
tracked!(export_executable_symbols, true);
736737
tracked!(dual_proc_macros, true);
737738
tracked!(fewer_names, Some(true));
738739
tracked!(force_unstable_if_unmarked, true);

compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,8 @@ options! {
12301230
an additional `.html` file showing the computed coverage spans."),
12311231
emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
12321232
"emit a section containing stack size metadata (default: no)"),
1233+
export_executable_symbols: bool = (false, parse_bool, [TRACKED],
1234+
"export symbols from executables, as if they were dynamic libraries"),
12331235
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
12341236
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
12351237
(default: no)"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-include ../../run-make-fulldeps/tools.mk
2+
3+
all:
4+
$(RUSTC) --edition=2018 --crate-type=cdylib foo.rs -o $(TMPDIR)/libfoo.so
5+
$(RUSTC) --edition=2018 -Zexport-executable-symbols -lfoo -L $(TMPDIR) main.rs -o $(TMPDIR)/main
6+
$(call $(TMPDIR)/main)
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
extern "C" {
2+
fn exported_symbol() -> i8;
3+
}
4+
5+
#[no_mangle]
6+
pub extern "C" fn call_exported_symbol() -> i8 {
7+
unsafe { exported_symbol() }
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// edition:2018
2+
3+
#![feature(rustc_private)]
4+
5+
extern crate libc;
6+
use std::ffi::*;
7+
use std::os::unix::ffi::*;
8+
9+
fn main() {
10+
let path = std::env::var("TMPDIR").unwrap();
11+
let path = std::path::PathBuf::from(path).join("libfoo.so");
12+
13+
let s = CString::new(path.as_os_str().as_bytes()).unwrap();
14+
let handle = unsafe { libc::dlopen(s.as_ptr(), libc::RTLD_LAZY | libc::RTLD_GLOBAL) };
15+
if handle.is_null() {
16+
let msg = unsafe { CStr::from_ptr(libc::dlerror() as *const _) };
17+
panic!("failed to dlopen lib {:?}", msg);
18+
}
19+
20+
unsafe {
21+
libc::dlerror();
22+
}
23+
24+
let raw_string = CString::new("call_exported_symbol").unwrap();
25+
let symbol = unsafe { libc::dlsym(handle as *mut libc::c_void, raw_string.as_ptr()) };
26+
if symbol.is_null() {
27+
let msg = unsafe { CStr::from_ptr(libc::dlerror() as *const _) };
28+
panic!("failed to load symbol {:?}", msg);
29+
}
30+
let func: extern "C" fn() -> i8 = unsafe { std::mem::transmute(symbol) };
31+
assert_eq!(func(), 42);
32+
}
33+
34+
#[no_mangle]
35+
pub fn exported_symbol() -> i8 {
36+
42
37+
}

0 commit comments

Comments
 (0)