Skip to content

Commit 6fe2ad8

Browse files
committed
use --dynamic-list for exporting executable symbols
1 parent 556d20a commit 6fe2ad8

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)