Skip to content

Commit

Permalink
Rollup merge of rust-lang#85673 - csmoe:export-exe-sym, r=bjorn3
Browse files Browse the repository at this point in the history
RFC-2841: add codegen flag export symbols from executable

Closes rust-lang#84161
r? ``@nikomatsakis`` ``@Mark-Simulacrum``
  • Loading branch information
Dylan-DPC authored Jun 21, 2022
2 parents 72fd41a + 09b0c55 commit 7efd34f
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 4 deletions.
13 changes: 9 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,9 +641,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.debugging_opts.export_executable_symbols
{
return;
}
}

// We manually create a list of exported symbols to ensure we don't expose any more.
Expand Down Expand Up @@ -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.debugging_opts.export_executable_symbols {
return;
}
}

let path = tmpdir.join("lib.def");
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,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);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,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<bool> = (None, parse_opt_bool, [TRACKED],
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
(default: no)"),
Expand Down
7 changes: 7 additions & 0 deletions src/test/run-make/export-executable-symbols/Makefile
Original file line number Diff line number Diff line change
@@ -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)

8 changes: 8 additions & 0 deletions src/test/run-make/export-executable-symbols/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extern "C" {
fn exported_symbol() -> i8;
}

#[no_mangle]
pub extern "C" fn call_exported_symbol() -> i8 {
unsafe { exported_symbol() }
}
37 changes: 37 additions & 0 deletions src/test/run-make/export-executable-symbols/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// edition:2018

#![feature(rustc_private)]

extern crate libc;
use std::ffi::*;
use std::os::unix::ffi::*;

fn main() {
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 fn exported_symbol() -> i8 {
42
}

0 comments on commit 7efd34f

Please sign in to comment.