From c6251a8799f316ca09211f971c3305322a0e3c93 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 4 Dec 2024 01:55:46 +0100 Subject: [PATCH] Make symbols.o trick work when linking with ld64 --- compiler/rustc_codegen_ssa/src/back/link.rs | 30 ++++++++++++++++++- .../include-all-symbols-linking/lib.rs | 3 +- .../include-all-symbols-linking/rmake.rs | 4 +-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ad81ff272c62f..a8fe233010e95 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2085,8 +2085,19 @@ fn add_linked_symbol_object( file.set_mangling(object::write::Mangling::None); } + // ld64 requires a relocation to load undefined symbols, see below. + let ld64_section_helper = if file.format() == object::BinaryFormat::MachO { + Some(file.add_section( + file.segment_name(object::write::StandardSegment::Text).to_vec(), + "__text".into(), + object::SectionKind::Text, + )) + } else { + None + }; + for (sym, kind) in symbols.iter() { - file.add_symbol(object::write::Symbol { + let symbol = file.add_symbol(object::write::Symbol { name: sym.clone().into(), value: 0, size: 0, @@ -2100,6 +2111,23 @@ fn add_linked_symbol_object( section: object::write::SymbolSection::Undefined, flags: object::SymbolFlags::None, }); + + // TODO: Explain. + if let Some(section) = ld64_section_helper { + // TODO: Use architecture-specific data. + let offset = file.section_mut(section).append_data(&[0, 0, 0, 20], 4); + file.add_relocation(section, object::write::Relocation { + offset, + addend: 0, + symbol, + flags: object::write::RelocationFlags::MachO { + r_type: object::macho::ARM64_RELOC_BRANCH26, + r_pcrel: true, + r_length: 2, + }, + }) + .expect("failed adding relocation"); + } } let path = tmpdir.join("symbols.o"); diff --git a/tests/run-make/include-all-symbols-linking/lib.rs b/tests/run-make/include-all-symbols-linking/lib.rs index 99508bcdaf314..73186ee99e3d9 100644 --- a/tests/run-make/include-all-symbols-linking/lib.rs +++ b/tests/run-make/include-all-symbols-linking/lib.rs @@ -1,5 +1,6 @@ mod foo { - #[link_section = ".rodata.STATIC"] + #[cfg_attr(target_os = "linux", link_section = ".rodata.STATIC")] + #[cfg_attr(target_vendor = "apple", link_section = "__DATA,STATIC")] #[used] static STATIC: [u32; 10] = [1; 10]; } diff --git a/tests/run-make/include-all-symbols-linking/rmake.rs b/tests/run-make/include-all-symbols-linking/rmake.rs index 77fd71ab20d21..222ef1f508173 100644 --- a/tests/run-make/include-all-symbols-linking/rmake.rs +++ b/tests/run-make/include-all-symbols-linking/rmake.rs @@ -7,7 +7,7 @@ // See https://github.com/rust-lang/rust/pull/95604 // See https://github.com/rust-lang/rust/issues/47384 -//@ only-linux +// TODO: Fix this file properly // Reason: differences in object file formats on OSX and Windows // causes errors in the llvm_objdump step @@ -15,7 +15,7 @@ use run_make_support::{dynamic_lib_name, llvm_objdump, llvm_readobj, rustc}; fn main() { rustc().crate_type("lib").input("lib.rs").run(); - rustc().crate_type("cdylib").link_args("-Tlinker.ld").input("main.rs").run(); + rustc().crate_type("cdylib").input("main.rs").run(); // Ensure `#[used]` and `KEEP`-ed section is there llvm_objdump() .arg("--full-contents")