diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7a13e424f9aca..4ba9de22ee96f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2263,7 +2263,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( sess: &'a Session, codegen_results: &CodegenResults, tmpdir: &Path, - crate_type: CrateType, + _crate_type: CrateType, cnum: CrateNum, ) { let src = &codegen_results.crate_info.used_crate_source[&cnum]; @@ -2274,13 +2274,15 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // whole of each object in our archive into that artifact. This is // because a `dylib` can be reused as an intermediate artifact. // + // NOTE(nbdd0121): Even for non-dylib, we still need to link rlibs + // in whole because so that `#[no_mangle]` and `#[used]` items from + // upstream need to be root (#47384, #50007). + // // Note, though, that we don't want to include the whole of a // compiler-builtins crate (e.g., compiler-rt) because it'll get // repeatedly linked anyway. let path = fix_windows_verbatim_for_gcc(path); - if crate_type == CrateType::Dylib - && codegen_results.crate_info.compiler_builtins != Some(cnum) - { + if codegen_results.crate_info.compiler_builtins != Some(cnum) { cmd.link_whole_rlib(&path); } else { cmd.link_rlib(&path); diff --git a/src/test/run-make/issue-47384/Makefile b/src/test/run-make/issue-47384/Makefile new file mode 100644 index 0000000000000..d3d48966b8547 --- /dev/null +++ b/src/test/run-make/issue-47384/Makefile @@ -0,0 +1,12 @@ +-include ../../run-make-fulldeps/tools.mk + +# ignore-windows +# ignore-cross-compile + +all: main.rs + $(RUSTC) --crate-type lib lib.rs + $(RUSTC) --crate-type cdylib -Clink-args="-Tlinker.ld" main.rs + # Ensure `#[used]` and `KEEP`-ed section is there + objdump -s -j".static" $(TMPDIR)/libmain.so + # Ensure `#[no_mangle]` symbol is there + nm $(TMPDIR)/libmain.so | $(CGREP) bar diff --git a/src/test/run-make/issue-47384/lib.rs b/src/test/run-make/issue-47384/lib.rs new file mode 100644 index 0000000000000..99508bcdaf314 --- /dev/null +++ b/src/test/run-make/issue-47384/lib.rs @@ -0,0 +1,12 @@ +mod foo { + #[link_section = ".rodata.STATIC"] + #[used] + static STATIC: [u32; 10] = [1; 10]; +} + +mod bar { + #[no_mangle] + extern "C" fn bar() -> i32 { + 0 + } +} diff --git a/src/test/run-make/issue-47384/linker.ld b/src/test/run-make/issue-47384/linker.ld new file mode 100644 index 0000000000000..2e70acab3f496 --- /dev/null +++ b/src/test/run-make/issue-47384/linker.ld @@ -0,0 +1,7 @@ +SECTIONS +{ + .static : ALIGN(4) + { + KEEP(*(.rodata.STATIC)); + } +} diff --git a/src/test/run-make/issue-47384/main.rs b/src/test/run-make/issue-47384/main.rs new file mode 100644 index 0000000000000..02572632517ec --- /dev/null +++ b/src/test/run-make/issue-47384/main.rs @@ -0,0 +1 @@ +extern crate lib;