set subsections_via_symbols for ld64 helper sections

This commit is contained in:
usamoi 2025-04-13 23:18:39 +08:00
parent 65fa0ab924
commit b1a38313cb
3 changed files with 53 additions and 0 deletions

View File

@ -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 {

View File

@ -0,0 +1,20 @@
//@ only-apple
//@ build-fail
//@ dont-check-compiler-stderr
//@ dont-check-compiler-stdout
// Regression test for <https://github.com/rust-lang/rust/issues/139744>.
// 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

View File

@ -0,0 +1,27 @@
//@ run-pass
//@ ignore-windows-gnu: only statics marked with used can be GC-ed on windows-gnu
// Regression test for <https://github.com/rust-lang/rust/issues/139744>.
// 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");
}