Skip to content

LTO and no_builtins: undefined references to standard Rust symbols errors at link time #72140

Description

@Deluvi

It seems that depending on a Rust library that has the attribute #![no_builtins] prevents the linker to provide the needed symbols to the library.

I made a repository to demonstrate this issue with a minimal reproduction case: Deluvi/bug-no-builtins-lto-rust. The instructions to run the example are in the README.

Here is an example error line (you can find the whole cargo output in the "Error output" drop down below):

/usr/bin/ld: no_builtins_lib.2derfq4u-cgu.2:(.text._ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve17h791963cb9aa36cdbE+0x7f): undefined reference to `__rust_alloc'

If you want the compilation to work, you can remove the `#![no_builtins] line and the compilation will work just fine.

Meta

rustc --version --verbose:

rustc 1.43.1 (8d69840ab 2020-05-04)
binary: rustc
commit-hash: 8d69840ab92ea7f4d323420088dd8c9775f180cd
commit-date: 2020-05-04
host: x86_64-unknown-linux-gnu
release: 1.43.1
LLVM version: 9.0
Error output

cargo run --release -p no-builtins-bin
   Compiling no-builtins-lib v0.1.0 (/home/deluvi/tests/test-lto/no-builtins-lib)
   Compiling no-builtins-bin v0.1.0 (/home/deluvi/tests/test-lto/no-builtins-bin)
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/deluvi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/deluvi/tests/test-lto/target/release/deps/no_builtins_bin-d28e15586db11f8b.no_builtins_bin.ds5ffvdz-cgu.7.rcgu.o" "-o" "/home/deluvi/tests/test-lto/target/release/deps/no_builtins_bin-d28e15586db11f8b" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-Wl,-O1" "-nodefaultlibs" "-L" "/home/deluvi/tests/test-lto/target/release/deps" "-L" "/home/deluvi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/home/deluvi/tests/test-lto/target/release/deps/libno_builtins_lib-cef2adf5c7c12373.rlib" "-Wl,--start-group" "/tmp/rustcvFiUgJ/libbacktrace_sys-dc606003556dfe9c.rlib" "-Wl,--end-group" "/home/deluvi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-2541f1e09df1c67d.rlib" "-Wl,-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
  = note: /usr/bin/ld: /home/deluvi/tests/test-lto/target/release/deps/libno_builtins_lib-cef2adf5c7c12373.rlib(no_builtins_lib-cef2adf5c7c12373.no_builtins_lib.2derfq4u-cgu.0.rcgu.o): in function `core::ptr::drop_in_place':
          no_builtins_lib.2derfq4u-cgu.0:(.text._ZN4core3ptr13drop_in_place17h107dbe4e36e3489dE+0x13): undefined reference to `__rust_dealloc'
          /usr/bin/ld: /home/deluvi/tests/test-lto/target/release/deps/libno_builtins_lib-cef2adf5c7c12373.rlib(no_builtins_lib-cef2adf5c7c12373.no_builtins_lib.2derfq4u-cgu.2.rcgu.o): in function `alloc::raw_vec::RawVec<T,A>::reserve':
          no_builtins_lib.2derfq4u-cgu.2:(.text._ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve17h791963cb9aa36cdbE+0x58): undefined reference to `__rust_realloc'
          /usr/bin/ld: no_builtins_lib.2derfq4u-cgu.2:(.text._ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve17h791963cb9aa36cdbE+0x7f): undefined reference to `__rust_alloc'
          /usr/bin/ld: no_builtins_lib.2derfq4u-cgu.2:(.text._ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve17h791963cb9aa36cdbE+0x8f): undefined reference to `__rust_dealloc'
          /usr/bin/ld: no_builtins_lib.2derfq4u-cgu.2:(.text._ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve17h791963cb9aa36cdbE+0x98): undefined reference to `core::alloc::Layout::dangling'
          /usr/bin/ld: no_builtins_lib.2derfq4u-cgu.2:(.text._ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve17h791963cb9aa36cdbE+0xa8): undefined reference to `core::alloc::Layout::dangling'
          /usr/bin/ld: no_builtins_lib.2derfq4u-cgu.2:(.text._ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve17h791963cb9aa36cdbE+0xc4): undefined reference to `alloc::raw_vec::capacity_overflow'
          /usr/bin/ld: no_builtins_lib.2derfq4u-cgu.2:(.text._ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve17h791963cb9aa36cdbE+0xd4): undefined reference to `alloc::alloc::handle_alloc_error'
          collect2: error: ld returned 1 exit status
          

error: aborting due to previous error

error: could not compile `no-builtins-bin`.

Activity

  1. added
    A-linkageArea: linking into static, shared libraries and binaries
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on May 12, 2020
  2. pnkfelix commented on Jul 17, 2023

    @pnkfelix
    Contributor

    Inspired by discussion on PR #109821, I made a variant test case (largely taken from @dianqk's "stable" demo for that PR, to find out the historical behavior of Rust on that example. (The main differences are that 1. I changed the test to use extern crate, in order to be able to build on older versions of Rust, 2. I changed it to use lto = true rather than lto = fat, again for backward compatibility with older versions of Rust, and 3. I had the code start returning a non-() value from the linked crate, specially a &'static str, so that I could double-check that the dynamic behavior is plausible.)

    Here is the main thing I've discovered so far: Rust 1.0 through 1.12 were able to compile and run the adapted example. It was back in Rust 1.13 that we started seeing this incompatbility between LTO and #![no_builtins], i.e. something along the lines of of:

    % cargo  +1.13 build --release
       Compiling bar v0.1.0 (file:///home/ubuntu/Dev/Rust/Linking/issue_72140/rust-109821-reproducible/stable/bar)
       Compiling foo v0.1.0 (file:///home/ubuntu/Dev/Rust/Linking/issue_72140/rust-109821-reproducible/stable/foo)
       Compiling tool v0.1.0 (file:///home/ubuntu/Dev/Rust/Linking/issue_72140/rust-109821-reproducible/stable)
    error: linking with `cc` failed: exit code: 1
      |
      = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/ubuntu/.rustup/toolchains/1.13-x86_64-unknown-linux-gnu/lib/rustlib/x86_6\
    4-unknown-linux-gnu/lib" "/home/ubuntu/Dev/Rust/Linking/issue_72140/rust-109821-reproducible/stable/target/release/tool.0.o" "-o" "/home/ubuntu/De\
    v/Rust/Linking/issue_72140/rust-109821-reproducible/stable/target/release/tool" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/home/ubuntu/Dev\
    /Rust/Linking/issue_72140/rust-109821-reproducible/stable/target/release/deps" "-L" "/home/ubuntu/.rustup/toolchains/1.13-x86_64-unknown-linux-gnu\
    /lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/tmp/rustc.C74lmNfGlWwA/libfoo.rlib" "/tmp/rustc.C74lmNfGlWwA/libstd-a4\
    729905.rlib" "/tmp/rustc.C74lmNfGlWwA/liballoc_jemalloc-a4729905.rlib" "/tmp/rustc.C74lmNfGlWwA/libcompiler_builtins-a4729905.rlib" "-l" "dl" "-l"\
     "pthread" "-l" "gcc_s" "-l" "pthread" "-l" "c" "-l" "m" "-l" "rt" "-l" "util"
      = note: /usr/bin/ld: /tmp/rustc.C74lmNfGlWwA/libfoo.rlib(foo.0.o): in function `foo::msg':
    foo.cgu-0.rs:(.text._ZN3foo3msg17hb7b968140369922eE+0x1): undefined reference to `bar::msg'
    collect2: error: ld returned 1 exit status
    

    So, this has been broken for a long time (i.e. since the end of 2016), but it hasn't "always" been broken.

  3. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Jul 17, 2023
  4. dianqk commented on Jul 18, 2023

    @dianqk
    Member

    Maybe now you could look at #113716. I added the no-builtins attribute to the function. We can get #![no_builtins] to participate in LTO again.

  5. pnkfelix commented on Jul 18, 2023

    @pnkfelix
    Contributor

    Oh, was PR #35637 the reason that this broke between 1.12 and 1.13?

  6. dianqk commented on Jul 18, 2023

    @dianqk
    Member

    Oh, was PR #35637 the reason that this broke between 1.12 and 1.13?

    Yes. The symbols required by #![no_builtins] are present in LTO, but they are not exported. #109821 is a possible solution.
    However, now I have found a more suitable solution, which is to let #![no_builtins] participate in LTO again.

  7. pnkfelix commented on Jul 18, 2023

    @pnkfelix
    Contributor

    Yeah I think #113716 (plus reverting #35637) sounds far more reasonable than PR #109821.

    (It still may not resolve some outstanding questions i have about what goes on with implicit dependencies on libcore, but that need not concern us here.)

  8. apiraino commented on Jul 18, 2023

    @apiraino
    Contributor

    WG-prioritization assigning priority (Zulip discussion).

    @rustbot label -I-prioritize +P-medium

  9. added and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Jul 18, 2023
  10. dianqk commented on Aug 10, 2023

    @dianqk
    Member

    @rustbot claim

  11. added a commit that references this issue on Sep 14, 2023
    807017a
  12. added 2 commits that reference this issue on Oct 12, 2023
    4a10160
    cfbbe70
  13. added 3 commits that reference this issue on Oct 26, 2023
    ea74e09
    c6441c1
    f56643a
  14. added 3 commits that reference this issue on Nov 14, 2023
    841c3b9
    80da666
    fffba52
  15. added 3 commits that reference this issue on Nov 30, 2023
    45ab772
    974b31a
    8c2b577
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions