Skip to content

Commit ea6a131

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

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -800,13 +800,11 @@ 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-
806803
debug!("EXPORTED SYMBOLS:");
807804

808805
if self.sess.target.is_like_darwin {
809806
// Write a plain, newline-separated list of symbols
807+
let path = tmpdir.join("list");
810808
let res: io::Result<()> = try {
811809
let mut f = File::create_buffered(&path)?;
812810
for (sym, _) in symbols {
@@ -817,7 +815,9 @@ 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 {
820+
let path = tmpdir.join("list.def");
821821
let res: io::Result<()> = try {
822822
let mut f = File::create_buffered(&path)?;
823823

@@ -835,7 +835,24 @@ impl<'a> Linker for GccLinker<'a> {
835835
if let Err(error) = res {
836836
self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error });
837837
}
838+
self.link_arg(path);
839+
} else if crate_type == CrateType::Executable && !self.sess.target.is_like_solaris {
840+
let path = tmpdir.join("list");
841+
let res: io::Result<()> = try {
842+
let mut f = File::create_buffered(&path)?;
843+
writeln!(f, "{{")?;
844+
for (sym, _) in symbols {
845+
debug!(sym);
846+
writeln!(f, " {sym};")?;
847+
}
848+
writeln!(f, "}};")?;
849+
};
850+
if let Err(error) = res {
851+
self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
852+
}
853+
self.link_arg("--dynamic-list").link_arg(path);
838854
} else {
855+
let path = tmpdir.join("list");
839856
// Write an LD version script
840857
let res: io::Result<()> = try {
841858
let mut f = File::create_buffered(&path)?;
@@ -852,18 +869,13 @@ impl<'a> Linker for GccLinker<'a> {
852869
if let Err(error) = res {
853870
self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
854871
}
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");
872+
if self.sess.target.is_like_solaris {
873+
self.link_arg("-M").link_arg(path);
874+
} else {
875+
let mut arg = OsString::from("--version-script=");
876+
arg.push(path);
877+
self.link_arg(arg).link_arg("--no-undefined-version");
878+
}
867879
}
868880
}
869881

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)