Skip to content

Commit b8518e7

Browse files
authored
Rollup merge of rust-lang#143846 - usamoi:gc, r=bjorn3
pass --gc-sections if -Zexport-executable-symbols is enabled and improve tests Exported symbols are added as GC roots in linking, so `--gc-sections` won't hurt `-Zexport-executable-symbols`. Fixes the run-make test to work on Linux. Enable the ui test on more targets. cc rust-lang#84161
2 parents fd39094 + 5bb6b9d commit b8518e7

File tree

4 files changed

+40
-56
lines changed

4 files changed

+40
-56
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,12 +2542,7 @@ fn add_order_independent_options(
25422542
// sections to ensure we have all the data for PGO.
25432543
let keep_metadata =
25442544
crate_type == CrateType::Dylib || sess.opts.cg.profile_generate.enabled();
2545-
if crate_type != CrateType::Executable || !sess.opts.unstable_opts.export_executable_symbols
2546-
{
2547-
cmd.gc_sections(keep_metadata);
2548-
} else {
2549-
cmd.no_gc_sections();
2550-
}
2545+
cmd.gc_sections(keep_metadata);
25512546
}
25522547

25532548
cmd.set_output_kind(link_output_kind, crate_type, out_filename);

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ pub(crate) trait Linker {
326326
link_or_cc_args(self, &[path]);
327327
}
328328
fn gc_sections(&mut self, keep_metadata: bool);
329-
fn no_gc_sections(&mut self);
330329
fn full_relro(&mut self);
331330
fn partial_relro(&mut self);
332331
fn no_relro(&mut self);
@@ -688,12 +687,6 @@ impl<'a> Linker for GccLinker<'a> {
688687
}
689688
}
690689

691-
fn no_gc_sections(&mut self) {
692-
if self.is_gnu || self.sess.target.is_like_wasm {
693-
self.link_arg("--no-gc-sections");
694-
}
695-
}
696-
697690
fn optimize(&mut self) {
698691
if !self.is_gnu && !self.sess.target.is_like_wasm {
699692
return;
@@ -1010,10 +1003,6 @@ impl<'a> Linker for MsvcLinker<'a> {
10101003
}
10111004
}
10121005

1013-
fn no_gc_sections(&mut self) {
1014-
self.link_arg("/OPT:NOREF,NOICF");
1015-
}
1016-
10171006
fn full_relro(&mut self) {
10181007
// noop
10191008
}
@@ -1243,10 +1232,6 @@ impl<'a> Linker for EmLinker<'a> {
12431232
// noop
12441233
}
12451234

1246-
fn no_gc_sections(&mut self) {
1247-
// noop
1248-
}
1249-
12501235
fn optimize(&mut self) {
12511236
// Emscripten performs own optimizations
12521237
self.cc_arg(match self.sess.opts.optimize {
@@ -1418,10 +1403,6 @@ impl<'a> Linker for WasmLd<'a> {
14181403
self.link_arg("--gc-sections");
14191404
}
14201405

1421-
fn no_gc_sections(&mut self) {
1422-
self.link_arg("--no-gc-sections");
1423-
}
1424-
14251406
fn optimize(&mut self) {
14261407
// The -O flag is, as of late 2023, only used for merging of strings and debuginfo, and
14271408
// only differentiates -O0 and -O1. It does not apply to LTO.
@@ -1567,10 +1548,6 @@ impl<'a> Linker for L4Bender<'a> {
15671548
}
15681549
}
15691550

1570-
fn no_gc_sections(&mut self) {
1571-
self.link_arg("--no-gc-sections");
1572-
}
1573-
15741551
fn optimize(&mut self) {
15751552
// GNU-style linkers support optimization with -O. GNU ld doesn't
15761553
// need a numeric argument, but other linkers do.
@@ -1734,10 +1711,6 @@ impl<'a> Linker for AixLinker<'a> {
17341711
self.link_arg("-bgc");
17351712
}
17361713

1737-
fn no_gc_sections(&mut self) {
1738-
self.link_arg("-bnogc");
1739-
}
1740-
17411714
fn optimize(&mut self) {}
17421715

17431716
fn pgo_gen(&mut self) {
@@ -1982,8 +1955,6 @@ impl<'a> Linker for PtxLinker<'a> {
19821955

19831956
fn gc_sections(&mut self, _keep_metadata: bool) {}
19841957

1985-
fn no_gc_sections(&mut self) {}
1986-
19871958
fn pgo_gen(&mut self) {}
19881959

19891960
fn no_crt_objects(&mut self) {}
@@ -2057,8 +2028,6 @@ impl<'a> Linker for LlbcLinker<'a> {
20572028

20582029
fn gc_sections(&mut self, _keep_metadata: bool) {}
20592030

2060-
fn no_gc_sections(&mut self) {}
2061-
20622031
fn pgo_gen(&mut self) {}
20632032

20642033
fn no_crt_objects(&mut self) {}
@@ -2139,8 +2108,6 @@ impl<'a> Linker for BpfLinker<'a> {
21392108

21402109
fn gc_sections(&mut self, _keep_metadata: bool) {}
21412110

2142-
fn no_gc_sections(&mut self) {}
2143-
21442111
fn pgo_gen(&mut self) {}
21452112

21462113
fn no_crt_objects(&mut self) {}

tests/run-make/export-executable-symbols/rmake.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,22 @@
44
// symbol.
55
// See https://github.com/rust-lang/rust/pull/85673
66

7-
//@ only-unix
8-
// Reason: the export-executable-symbols flag only works on Unix
9-
// due to hardcoded platform-specific implementation
10-
// (See #85673)
11-
//@ ignore-cross-compile
127
//@ ignore-wasm
8+
//@ ignore-cross-compile
139

14-
use run_make_support::{bin_name, llvm_readobj, rustc};
10+
use run_make_support::object::Object;
11+
use run_make_support::{bin_name, is_darwin, object, rustc};
1512

1613
fn main() {
17-
rustc().arg("-Zexport-executable-symbols").input("main.rs").crate_type("bin").run();
18-
llvm_readobj()
19-
.symbols()
20-
.input(bin_name("main"))
21-
.run()
22-
.assert_stdout_contains("exported_symbol");
14+
rustc()
15+
.arg("-Ctarget-feature=-crt-static")
16+
.arg("-Zexport-executable-symbols")
17+
.input("main.rs")
18+
.crate_type("bin")
19+
.run();
20+
let name: &[u8] = if is_darwin() { b"_exported_symbol" } else { b"exported_symbol" };
21+
let contents = std::fs::read(bin_name("main")).unwrap();
22+
let object = object::File::parse(contents.as_slice()).unwrap();
23+
let found = object.exports().unwrap().iter().any(|x| x.name() == name);
24+
assert!(found);
2325
}
Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
//@ run-pass
2-
//@ only-linux
3-
//@ only-gnu
4-
//@ compile-flags: -Zexport-executable-symbols
2+
//@ compile-flags: -Ctarget-feature=-crt-static -Zexport-executable-symbols
3+
//@ ignore-wasm
4+
//@ ignore-cross-compile
55
//@ edition: 2024
66

77
// Regression test for <https://github.com/rust-lang/rust/issues/101610>.
88

99
#![feature(rustc_private)]
1010

11-
extern crate libc;
12-
1311
#[unsafe(no_mangle)]
1412
fn hack() -> u64 {
1513
998244353
1614
}
1715

1816
fn main() {
17+
#[cfg(unix)]
1918
unsafe {
19+
extern crate libc;
2020
let handle = libc::dlopen(std::ptr::null(), libc::RTLD_NOW);
2121
let ptr = libc::dlsym(handle, c"hack".as_ptr());
2222
let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr);
@@ -27,4 +27,24 @@ fn main() {
2727
panic!("symbol `hack` is not found");
2828
}
2929
}
30+
#[cfg(windows)]
31+
unsafe {
32+
type PCSTR = *const u8;
33+
type HMODULE = *mut core::ffi::c_void;
34+
type FARPROC = Option<unsafe extern "system" fn() -> isize>;
35+
#[link(name = "kernel32", kind = "raw-dylib")]
36+
unsafe extern "system" {
37+
fn GetModuleHandleA(lpmodulename: PCSTR) -> HMODULE;
38+
fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC;
39+
}
40+
let handle = GetModuleHandleA(std::ptr::null_mut());
41+
let ptr = GetProcAddress(handle, b"hack\0".as_ptr());
42+
let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr);
43+
if let Some(f) = ptr {
44+
assert!(f() == 998244353);
45+
println!("symbol `hack` is found successfully");
46+
} else {
47+
panic!("symbol `hack` is not found");
48+
}
49+
}
3050
}

0 commit comments

Comments
 (0)