Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libtest fails to link with lld at main #105967

Closed
andrewpollack opened this issue Dec 20, 2022 · 7 comments · Fixed by #108017
Closed

libtest fails to link with lld at main #105967

andrewpollack opened this issue Dec 20, 2022 · 7 comments · Fixed by #108017
Assignees
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@andrewpollack
Copy link
Member

andrewpollack commented Dec 20, 2022

Building Rust toolchain using latest lld linker at hash 6443c0ee02c7785bc917fcf508f4cc7ded38487a leads to an error when compiling libtest at stage0:

Building stage0 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
   Compiling cc v1.0.76
   Compiling core v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/core)
   Compiling libc v0.2.138
   Compiling memchr v2.5.0
   Compiling std v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/std)
   Compiling compiler_builtins v0.1.85
   Compiling unwind v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/unwind)
   Compiling profiler_builtins v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/profiler_builtins)
   Compiling rustc-std-workspace-core v1.99.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/rustc-std-workspace-core)
   Compiling alloc v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/alloc)
   Compiling cfg-if v1.0.0
   Compiling adler v1.0.2
   Compiling rustc-demangle v0.1.21
   Compiling rustc-std-workspace-alloc v1.99.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/rustc-std-workspace-alloc)
   Compiling panic_abort v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/panic_abort)
   Compiling panic_unwind v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/panic_unwind)
   Compiling gimli v0.26.1
   Compiling miniz_oxide v0.5.3
   Compiling std_detect v0.1.5 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/stdarch/crates/std_detect)
   Compiling hashbrown v0.12.3
   Compiling object v0.29.0
   Compiling addr2line v0.17.0
   Compiling rustc-std-workspace-std v1.99.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/rustc-std-workspace-std)
   Compiling proc_macro v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/proc_macro)
   Compiling unicode-width v0.1.10
   Compiling getopts v0.2.21
   Compiling test v0.0.0 (/b/s/w/ir/x/w/fuchsia-third_party-rust/library/test)
error: linking with `/b/s/w/ir/x/w/cipd/bin/clang++` failed: exit status: 1
  |
  = note: "/b/s/w/ir/x/w/cipd/bin/clang++" "-Wl,--version-script=/b/s/w/ir/x/t/rustctgpUpK/list" "-m64" "/b/s/w/ir/x/t/rustctgpUpK/symbols.o" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/test-3bd20e94ef73cd68.test.d3d4ef93-cgu.0.rcgu.o" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/test-3bd20e94ef73cd68.1w1vzuec12odskdf.rcgu.rmeta" "-Wl,--as-needed" "-L" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps" "-L" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/release/deps" "-L" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/build/compiler_builtins-1f459caf2b14046b/out" "-L" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/build/profiler_builtins-a255468473e62d4f/out" "-L" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-sysroot/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/libgetopts-023b5f868ec7a238.rlib" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/libunicode_width-e0099b6d5dcba458.rlib" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/librustc_std_workspace_std-8f7f1564c2f2e122.rlib" "-L" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps" "-Wl,-Bdynamic" "-lstd-77833ca844ade20f" "-Wl,-Bstatic" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/libcompiler_builtins-63346244df871953.rlib" "-Wl,-Bdynamic" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-sysroot/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/b/s/w/ir/x/w/staging/build/fuchsia-build/x86_64-unknown-linux-gnu/stage0-std/x86_64-unknown-linux-gnu/release/deps/libtest-3bd20e94ef73cd68.so" "-shared" "-Wl,-zrelro,-znow" "-Wl,-O1" "-nodefaultlibs" "--target=x86_64-unknown-linux-gnu" "--sysroot=/b/s/w/ir/x/w/cipd/linux" "-fuse-ld=lld" "-Wl,-z,origin" "-Wl,-rpath,$ORIGIN/../lib"
  = note: ld.lld: error: version script assignment of 'global' to symbol '__rust_alloc' failed: symbol not defined
          ld.lld: error: version script assignment of 'global' to symbol '__rust_alloc_error_handler_should_panic' failed: symbol not defined
          ld.lld: error: version script assignment of 'global' to symbol '__rust_alloc_zeroed' failed: symbol not defined
          ld.lld: error: version script assignment of 'global' to symbol '__rust_dealloc' failed: symbol not defined
          ld.lld: error: version script assignment of 'global' to symbol '__rust_realloc' failed: symbol not defined
          clang-16: error: linker command failed with exit code 1 (use -v to see invocation)
          
error: could not compile `test` due to previous error

Error is coming from https://reviews.llvm.org/D135402 (Enable --no-undefined-version by default.), with the description indicating that our version scripts were not correct.

Local workaround is to pass -Clink-arg=-Wl,--undefined-version in Rustflags.

@andrewpollack andrewpollack added the C-bug Category: This is a bug. label Dec 20, 2022
@tmandry tmandry added A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 20, 2022
berkley4 added a commit to berkley4/ungoogled-chromium-debian that referenced this issue Jan 5, 2023
Similar in nature to rust-lang/rust#105967
I was getting the following at the final chrome link stage :-

ld.lld: error: version script assignment of 'global' to symbol \
'__libc_csu_fini' failed: symbol not defined
ld.lld: error: version script assignment of 'global' to symbol \
'__libc_csu_init' failed: symbol not defined

The explanation at https://reviews.llvm.org/D140591#4014995 seems to
point to my self-compiled llvm/clang perhaps lacking one or both of
libcxx and libcxxabi (-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"),
which may have avoided the issue.

Bundled clang users probably won't need to enable the patch.
@chbaker0
Copy link
Contributor

chbaker0 commented Feb 8, 2023

I ran into this too.

I wonder why rustc is attempting to export those symbols from test, but not std? I'm seeing that e.g. x.py build --stage 0 library/std works but x.py build --stage 0 library/test does not. I can't determine what's different between std and test that would cause only the latter to output an invalid version script.

@chbaker0
Copy link
Contributor

chbaker0 commented Feb 10, 2023

This actually repros outside of test. If you attempt to compile any crate as a dylib, and std is available as a dylib and linked as such (e.g. with the -Cprefer-dynamic) flag, you can reproduce the error by simply passing -Clink-arg=-Wl,--no-undefined-version. This was with stable rustc and my system gcc.

Hopefully reproducing it outside of Rust's bootstrap will make it easier to debug.

@chbaker0
Copy link
Contributor

I suspect I found the issue:

First, early in compilation rustc determines if a crate needs an allocator (whether or not it comes from the crate itself, or a dep). This is filled in a crate metadata struct field:

/// This crate needs an allocator and either provides it itself, or finds it in a dependency.
/// If the above is true, then this field denotes the kind of the found allocator.
allocator_kind: Option<AllocatorKind>,

If Some(_), the field says whether the crate graph contains a #[global_allocator] or not, but that's not directly relevant to the bug. This field will usually be Some(_); it's None if std and alloc are not used.

Later, rustc checks whether to codegen the __rust_alloc et al functions:

// Codegen an allocator shim, if necessary.
//
// If the crate doesn't have an `allocator_kind` set then there's definitely
// no shim to generate. Otherwise we also check our dependency graph for all
// our output crate types. If anything there looks like its a `Dynamic`
// linkage, then it's already got an allocator shim and we'll be using that
// one instead. If nothing exists then it's our job to generate the
// allocator!
let any_dynamic_crate = tcx.dependency_formats(()).iter().any(|(_, list)| {
use rustc_middle::middle::dependency_format::Linkage;
list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
let allocator_module = if any_dynamic_crate {
None
} else if let Some(kind) = tcx.allocator_kind(()) {
let llmod_id =
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
let module_llvm = tcx.sess.time("write_allocator_module", || {
backend.codegen_allocator(
tcx,
&llmod_id,
kind,
// If allocator_kind is Some then alloc_error_handler_kind must
// also be Some.
tcx.alloc_error_handler_kind(()).unwrap(),
)
});
Some(ModuleCodegen { name: llmod_id, module_llvm, kind: ModuleKind::Allocator })
} else {
None
};

Notably, if any dependency is linked as a dylib, it will not generate them and instead link to the implementations exported from another dylib.

Independently, rustc determines which symbols to export when generating a dylib and provides this list to the linker. Part of this is deciding whether to export the allocator symbols:

if tcx.allocator_kind(()).is_some() {
for symbol_name in ALLOCATOR_METHODS
.iter()
.map(|method| format!("__rust_{}", method.name))
.chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()])
{
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
symbols.push((
exported_symbol,
SymbolExportInfo {
level: SymbolExportLevel::Rust,
kind: SymbolExportKind::Text,
used: false,
},
));
}
symbols.push((
ExportedSymbol::NoDefId(SymbolName::new(tcx, OomStrategy::SYMBOL)),
SymbolExportInfo {
level: SymbolExportLevel::Rust,
kind: SymbolExportKind::Text,
used: false,
},
));
}

Notably it does not perform the check from the last step. Even if a dylib dependency is linked whose allocator symbols this crate should use, the export list still contains these symbol names. So when building a dylib that links another dylib, rustc tells the linker to export symbols that weren't actually defined. The library/test build failure is just one instance of this bug.

@bjorn3 who helped in the Zulip discussion. Can you confirm this explanation makes sense?

@bjorn3
Copy link
Member

bjorn3 commented Feb 13, 2023

Most of it. There is a further complication that you can specify multiple crate types for a single compilation. It is then possible for some crate types to generate the allocator shim while others don't generate it. The list of exported symbols however is for all crate types at the same time.

One way to fix this would be to have a separate list of exported symbols for each crate type. Another option would be to move the addition of the __rust_* symbols to the actual code that invokes the linker.

@chbaker0
Copy link
Contributor

Listing exported symbols per crate type seems like the most correct fix in principle, but the lists will be almost the same except for the allocator symbols. I'll try to find a clean way to do the latter.

@chbaker0
Copy link
Contributor

@rustbot claim

JohnTitor added a commit to JohnTitor/rust that referenced this issue Mar 8, 2023
Add `--no-undefined-version` link flag and fix associated breakage

LLVM upstream sets `--no-undefined-version` by default in lld: https://reviews.llvm.org/D135402.

Due to a bug in how version scripts are generated, this breaks the `dylib` output type for most crates. See rust-lang#105967 (comment) for details.

This PR adds the flag to gcc flavor linkers in anticipation of this LLVM change rolling in, and patches `rustc` to not attempt to export `__rust_*` allocator symbols when they weren't generated.

Fixes rust-lang#105967
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 8, 2023
Add `--no-undefined-version` link flag and fix associated breakage

LLVM upstream sets `--no-undefined-version` by default in lld: https://reviews.llvm.org/D135402.

Due to a bug in how version scripts are generated, this breaks the `dylib` output type for most crates. See rust-lang#105967 (comment) for details.

This PR adds the flag to gcc flavor linkers in anticipation of this LLVM change rolling in, and patches `rustc` to not attempt to export `__rust_*` allocator symbols when they weren't generated.

Fixes rust-lang#105967
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 10, 2023
Add `--no-undefined-version` link flag and fix associated breakage

LLVM upstream sets `--no-undefined-version` by default in lld: https://reviews.llvm.org/D135402.

Due to a bug in how version scripts are generated, this breaks the `dylib` output type for most crates. See rust-lang#105967 (comment) for details.

This PR adds the flag to gcc flavor linkers in anticipation of this LLVM change rolling in, and patches `rustc` to not attempt to export `__rust_*` allocator symbols when they weren't generated.

Fixes rust-lang#105967
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 10, 2023
Add `--no-undefined-version` link flag and fix associated breakage

LLVM upstream sets `--no-undefined-version` by default in lld: https://reviews.llvm.org/D135402.

Due to a bug in how version scripts are generated, this breaks the `dylib` output type for most crates. See rust-lang#105967 (comment) for details.

This PR adds the flag to gcc flavor linkers in anticipation of this LLVM change rolling in, and patches `rustc` to not attempt to export `__rust_*` allocator symbols when they weren't generated.

Fixes rust-lang#105967
@bors bors closed this as completed in 342ca46 Mar 11, 2023
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this issue Mar 13, 2023
Add `--no-undefined-version` link flag and fix associated breakage

LLVM upstream sets `--no-undefined-version` by default in lld: https://reviews.llvm.org/D135402.

Due to a bug in how version scripts are generated, this breaks the `dylib` output type for most crates. See rust-lang/rust#105967 (comment) for details.

This PR adds the flag to gcc flavor linkers in anticipation of this LLVM change rolling in, and patches `rustc` to not attempt to export `__rust_*` allocator symbols when they weren't generated.

Fixes #105967
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Jun 9, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Jun 9, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Jun 11, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Jun 12, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Jun 16, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Jun 21, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Jun 24, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Oct 29, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 5, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 7, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 8, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 10, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 12, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 12, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 14, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 15, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 18, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 18, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 21, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 22, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 24, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 25, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Nov 27, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Dec 5, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Dec 11, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Dec 12, 2023
nickersk added a commit to nickersk/oe-alliance-core that referenced this issue Dec 20, 2023
tstein added a commit to tstein/termux-packages that referenced this issue Dec 24, 2023
…ilding.

Saw this in termux#18758. llvm appears to have upgraded a warning to an error
(https://reviews.llvm.org/D135402), and while they're not wrong to do
so, this package and others
(rust-lang/rust#105967) depended on it. This
is the simple fix, per the llvm reviews link.

Fixes termux#18750.
licy183 pushed a commit to termux/termux-packages that referenced this issue Dec 25, 2023
…18813)

Saw this in #18758. llvm appears to have upgraded a warning to an error
(https://reviews.llvm.org/D135402), and while they're not wrong to do
so, this package and others
(rust-lang/rust#105967) depended on it. This
is the simple fix, per the llvm reviews link.

Fixes #18750

[skip ci]
termux-pacman-bot added a commit to termux-pacman/termux-packages that referenced this issue Dec 25, 2023
…(#18813)

Saw this in #18758. llvm appears to have upgraded a warning to an error
(https://reviews.llvm.org/D135402), and while they're not wrong to do
so, this package and others
(rust-lang/rust#105967) depended on it. This
is the simple fix, per the llvm reviews link.

Fixes #18750

[skip ci]
WTNLXTBL added a commit to WTNLXTBL/termux-packages that referenced this issue Dec 25, 2023
…(#18813)

Saw this in #18758. llvm appears to have upgraded a warning to an error
(https://reviews.llvm.org/D135402), and while they're not wrong to do
so, this package and others
(rust-lang/rust#105967) depended on it. This
is the simple fix, per the llvm reviews link.

Fixes #18750

[skip ci]
WTNLXTBL added a commit to WTNLXTBL/termux-packages-pacman that referenced this issue Dec 25, 2023
…(#18813)

Saw this in #18758. llvm appears to have upgraded a warning to an error
(https://reviews.llvm.org/D135402), and while they're not wrong to do
so, this package and others
(rust-lang/rust#105967) depended on it. This
is the simple fix, per the llvm reviews link.

Fixes #18750

[skip ci]
bigbio2002 pushed a commit to bigbio2002/termux-packages that referenced this issue Feb 27, 2024
…ermux#18813)

Saw this in termux#18758. llvm appears to have upgraded a warning to an error
(https://reviews.llvm.org/D135402), and while they're not wrong to do
so, this package and others
(rust-lang/rust#105967) depended on it. This
is the simple fix, per the llvm reviews link.

Fixes termux#18750

[skip ci]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants