Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2542,12 +2542,9 @@ fn add_order_independent_options(
// sections to ensure we have all the data for PGO.
let keep_metadata =
crate_type == CrateType::Dylib || sess.opts.cg.profile_generate.enabled();
if crate_type != CrateType::Executable || !sess.opts.unstable_opts.export_executable_symbols
{
cmd.gc_sections(keep_metadata);
} else {
cmd.no_gc_sections();
}
cmd.gc_sections(keep_metadata);
} else {
cmd.no_gc_sections();
Copy link
Contributor Author

@usamoi usamoi Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removed line is the only place in rustc where no_gc_sections is called, so I had to call it here to suppress the unused warning.

Copy link
Member

@bjorn3 bjorn3 Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the no_gc_sections method entirely would also work, right? Your current change would change the behavior of -Clink-dead-code=yes, not just the behavior of -Zexport-executable-symbols.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no_gc_sections is removed now.

}

cmd.set_output_kind(link_output_kind, crate_type, out_filename);
Expand Down
25 changes: 13 additions & 12 deletions tests/run-make/export-executable-symbols/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
// symbol.
// See https://github.com/rust-lang/rust/pull/85673

//@ only-unix
// Reason: the export-executable-symbols flag only works on Unix
// due to hardcoded platform-specific implementation
// (See #85673)
//@ ignore-cross-compile
//@ ignore-wasm

use run_make_support::{bin_name, llvm_readobj, rustc};
use run_make_support::object::Object;
use run_make_support::{bin_name, is_darwin, object, rustc};

fn main() {
rustc().arg("-Zexport-executable-symbols").input("main.rs").crate_type("bin").run();
llvm_readobj()
.symbols()
.input(bin_name("main"))
.run()
.assert_stdout_contains("exported_symbol");
rustc()
.arg("-Ctarget-feature=-crt-static")
.arg("-Zexport-executable-symbols")
.input("main.rs")
.crate_type("bin")
.run();
let name: &[u8] = if is_darwin() { b"_exported_symbol" } else { b"exported_symbol" };
let contents = std::fs::read(bin_name("main")).unwrap();
let object = object::File::parse(contents.as_slice()).unwrap();
let found = object.exports().unwrap().iter().any(|x| x.name() == name);
assert!(found);
}
29 changes: 24 additions & 5 deletions tests/ui/linking/export-executable-symbols.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
//@ run-pass
//@ only-linux
//@ only-gnu
//@ compile-flags: -Zexport-executable-symbols
//@ compile-flags: -Ctarget-feature=-crt-static -Zexport-executable-symbols
//@ ignore-wasm
//@ edition: 2024

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

#![feature(rustc_private)]

extern crate libc;

#[unsafe(no_mangle)]
fn hack() -> u64 {
998244353
}

fn main() {
#[cfg(unix)]
unsafe {
extern crate libc;
let handle = libc::dlopen(std::ptr::null(), libc::RTLD_NOW);
let ptr = libc::dlsym(handle, c"hack".as_ptr());
let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr);
Expand All @@ -27,4 +26,24 @@ fn main() {
panic!("symbol `hack` is not found");
}
}
#[cfg(windows)]
unsafe {
type PCSTR = *const u8;
type HMODULE = *mut core::ffi::c_void;
type FARPROC = Option<unsafe extern "system" fn() -> isize>;
#[link(name = "kernel32", kind = "raw-dylib")]
unsafe extern "system" {
fn GetModuleHandleA(lpmodulename: PCSTR) -> HMODULE;
fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC;
}
let handle = GetModuleHandleA(std::ptr::null_mut());
let ptr = GetProcAddress(handle, b"hack\0".as_ptr());
let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr);
if let Some(f) = ptr {
assert!(f() == 998244353);
println!("symbol `hack` is found successfully");
} else {
panic!("symbol `hack` is not found");
}
}
}
Loading