From af256f2beea6364ef6f2cadf2b86f56dacd3a075 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Tue, 8 Feb 2022 21:24:35 +0000 Subject: [PATCH 1/2] Force rlibs to be linked in whole --- compiler/rustc_codegen_ssa/src/back/link.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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); From e76087711074d323ff9c538dbdfd501b9271774c Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Wed, 9 Feb 2022 00:02:51 +0000 Subject: [PATCH 2/2] Add a test for issue 47384 --- src/test/run-make/issue-47384/Makefile | 12 ++++++++++++ src/test/run-make/issue-47384/lib.rs | 12 ++++++++++++ src/test/run-make/issue-47384/linker.ld | 7 +++++++ src/test/run-make/issue-47384/main.rs | 1 + 4 files changed, 32 insertions(+) create mode 100644 src/test/run-make/issue-47384/Makefile create mode 100644 src/test/run-make/issue-47384/lib.rs create mode 100644 src/test/run-make/issue-47384/linker.ld create mode 100644 src/test/run-make/issue-47384/main.rs 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;