From b1a38313cb0dee9a7c5573ae37ad48b0a347cb7c Mon Sep 17 00:00:00 2001 From: usamoi Date: Sun, 13 Apr 2025 23:18:39 +0800 Subject: [PATCH] set subsections_via_symbols for ld64 helper sections --- compiler/rustc_codegen_ssa/src/back/link.rs | 6 +++++ tests/ui/linking/cdylib-no-mangle.rs | 20 ++++++++++++++ .../ui/linking/executable-no-mangle-strip.rs | 27 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 tests/ui/linking/cdylib-no-mangle.rs create mode 100644 tests/ui/linking/executable-no-mangle-strip.rs diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 8de68925cabbc..f0c47ac41e8a0 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2015,6 +2015,12 @@ fn add_linked_symbol_object( file.set_mangling(object::write::Mangling::None); } + if file.format() == object::BinaryFormat::MachO { + // Divide up the sections into sub-sections via symbols for dead code stripping. + // Without this flag, unused `#[no_mangle]` or `#[used]` cannot be discard on MachO targets. + file.set_subsections_via_symbols(); + } + // ld64 requires a relocation to load undefined symbols, see below. // Not strictly needed if linking with lld, but might as well do it there too. let ld64_section_helper = if file.format() == object::BinaryFormat::MachO { diff --git a/tests/ui/linking/cdylib-no-mangle.rs b/tests/ui/linking/cdylib-no-mangle.rs new file mode 100644 index 0000000000000..f442c3f584d6e --- /dev/null +++ b/tests/ui/linking/cdylib-no-mangle.rs @@ -0,0 +1,20 @@ +//@ only-apple +//@ build-fail +//@ dont-check-compiler-stderr +//@ dont-check-compiler-stdout + +// Regression test for . +// Functions in the dynamic library marked with no_mangle should not be GC-ed. + +#![crate_type = "cdylib"] + +unsafe extern "C" { + unsafe static THIS_SYMBOL_SHOULD_BE_UNDEFINED: usize; +} + +#[unsafe(no_mangle)] +pub unsafe fn function_marked_with_no_mangle() { + println!("FUNCTION_MARKED_WITH_NO_MANGLE = {}", unsafe { THIS_SYMBOL_SHOULD_BE_UNDEFINED }); +} + +//~? ERROR linking diff --git a/tests/ui/linking/executable-no-mangle-strip.rs b/tests/ui/linking/executable-no-mangle-strip.rs new file mode 100644 index 0000000000000..cc283dc53ee3a --- /dev/null +++ b/tests/ui/linking/executable-no-mangle-strip.rs @@ -0,0 +1,27 @@ +//@ run-pass +//@ ignore-windows-gnu: only statics marked with used can be GC-ed on windows-gnu + +// Regression test for . +// Functions in the binary marked with no_mangle should be GC-ed if they +// are not indirectly referenced by main. + +#![feature(used_with_arg)] + +#[cfg_attr(windows, link(name = "this_lib_does_not_exist", kind = "raw-dylib"))] +unsafe extern "C" { + unsafe static THIS_SYMBOL_SHOULD_BE_UNDEFINED: usize; +} + +#[unsafe(no_mangle)] +pub unsafe fn function_marked_with_no_mangle() { + println!("FUNCTION_MARKED_WITH_NO_MANGLE = {}", unsafe { THIS_SYMBOL_SHOULD_BE_UNDEFINED }); +} + +#[used(compiler)] +pub static FUNCTION_MARKED_WITH_USED: unsafe fn() = || { + println!("FUNCTION_MARKED_WITH_USED = {}", unsafe { THIS_SYMBOL_SHOULD_BE_UNDEFINED }); +}; + +fn main() { + println!("MAIN"); +}