Skip to content

Commit c1bb3b8

Browse files
authored
Rollup merge of #143446 - usamoi:export-executable-symbols, r=bjorn3,oli-obk
use `--dynamic-list` for exporting executable symbols closes #101610 cc #84161 https://sourceware.org/binutils/docs-2.39/ld/VERSION.html: > --dynamic-list=dynamic-list-file Specify the name of a dynamic list file to the linker. This is typically used when creating shared libraries to specify a list of global symbols whose references shouldn’t be bound to the definition within the shared library, or creating dynamically linked executables to specify a list of symbols which should be added to the symbol table in the executable. This option is only meaningful on ELF platforms which support shared libraries. `ld.lld --help`: > --dynamic-list=<file>: Similar to --export-dynamic-symbol-list. When creating a shared object, this additionally implies -Bsymbolic but does not set DF_SYMBOLIC > --export-dynamic-symbol-list=file: Read a list of dynamic symbol patterns. Apply --export-dynamic-symbol on each pattern > --export-dynamic-symbol=glob: (executable) Put matched symbols in the dynamic symbol table. (shared object) References to matched non-local STV_DEFAULT symbols shouldn't be bound to definitions within the shared object. Does not imply -Bsymbolic. > --export-dynamic: Put symbols in the dynamic symbol table Use `--dynamic-list` because it's older than `--export-dynamic-symbol-list` (binutils 2.35)
2 parents 0e676f4 + 6fe2ad8 commit c1bb3b8

File tree

2 files changed

+54
-16
lines changed

2 files changed

+54
-16
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -800,9 +800,7 @@ impl<'a> Linker for GccLinker<'a> {
800800
return;
801801
}
802802

803-
let is_windows = self.sess.target.is_like_windows;
804-
let path = tmpdir.join(if is_windows { "list.def" } else { "list" });
805-
803+
let path = tmpdir.join(if self.sess.target.is_like_windows { "list.def" } else { "list" });
806804
debug!("EXPORTED SYMBOLS:");
807805

808806
if self.sess.target.is_like_darwin {
@@ -817,7 +815,8 @@ impl<'a> Linker for GccLinker<'a> {
817815
if let Err(error) = res {
818816
self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error });
819817
}
820-
} else if is_windows {
818+
self.link_arg("-exported_symbols_list").link_arg(path);
819+
} else if self.sess.target.is_like_windows {
821820
let res: io::Result<()> = try {
822821
let mut f = File::create_buffered(&path)?;
823822

@@ -835,6 +834,21 @@ impl<'a> Linker for GccLinker<'a> {
835834
if let Err(error) = res {
836835
self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error });
837836
}
837+
self.link_arg(path);
838+
} else if crate_type == CrateType::Executable && !self.sess.target.is_like_solaris {
839+
let res: io::Result<()> = try {
840+
let mut f = File::create_buffered(&path)?;
841+
writeln!(f, "{{")?;
842+
for (sym, _) in symbols {
843+
debug!(sym);
844+
writeln!(f, " {sym};")?;
845+
}
846+
writeln!(f, "}};")?;
847+
};
848+
if let Err(error) = res {
849+
self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
850+
}
851+
self.link_arg("--dynamic-list").link_arg(path);
838852
} else {
839853
// Write an LD version script
840854
let res: io::Result<()> = try {
@@ -852,18 +866,13 @@ impl<'a> Linker for GccLinker<'a> {
852866
if let Err(error) = res {
853867
self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
854868
}
855-
}
856-
857-
if self.sess.target.is_like_darwin {
858-
self.link_arg("-exported_symbols_list").link_arg(path);
859-
} else if self.sess.target.is_like_solaris {
860-
self.link_arg("-M").link_arg(path);
861-
} else if is_windows {
862-
self.link_arg(path);
863-
} else {
864-
let mut arg = OsString::from("--version-script=");
865-
arg.push(path);
866-
self.link_arg(arg).link_arg("--no-undefined-version");
869+
if self.sess.target.is_like_solaris {
870+
self.link_arg("-M").link_arg(path);
871+
} else {
872+
let mut arg = OsString::from("--version-script=");
873+
arg.push(path);
874+
self.link_arg(arg).link_arg("--no-undefined-version");
875+
}
867876
}
868877
}
869878

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//@ run-pass
2+
//@ only-linux
3+
//@ compile-flags: -Zexport-executable-symbols
4+
//@ edition: 2024
5+
6+
// Regression test for <https://github.com/rust-lang/rust/issues/101610>.
7+
8+
#![feature(rustc_private)]
9+
10+
extern crate libc;
11+
12+
#[unsafe(no_mangle)]
13+
fn hack() -> u64 {
14+
998244353
15+
}
16+
17+
fn main() {
18+
unsafe {
19+
let handle = libc::dlopen(std::ptr::null(), libc::RTLD_NOW);
20+
let ptr = libc::dlsym(handle, c"hack".as_ptr());
21+
let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr);
22+
if let Some(f) = ptr {
23+
assert!(f() == 998244353);
24+
println!("symbol `hack` is found successfully");
25+
} else {
26+
panic!("symbol `hack` is not found");
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)