Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 946321 - dev-lang/rust-bin-*-r101[llvm-libunwind]: Cannot find symbol after patchelf on llvm profile.
Summary: dev-lang/rust-bin-*-r101[llvm-libunwind]: Cannot find symbol after patchelf o...
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: Normal normal
Assignee: Gentoo Rust Project
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-12-12 14:06 UTC by matheritasiv
Modified: 2024-12-27 18:20 UTC (History)
10 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
emerge --info (emerge-info.txt,6.95 KB, text/plain)
2024-12-13 10:32 UTC, matheritasiv
Details

Note You need to log in before you can comment on or make changes to this bug.
Description matheritasiv 2024-12-12 14:06:40 UTC
```
$ /opt/rust-bin-1.82.0/bin/rustc -v
/opt/rust-bin-1.82.0/bin/rustc: symbol lookup error: /opt/rust-bin-1.82.0/bin/../lib/../lib/libLLVM.so.19.1-rust-1.82.0-stable: undefined symbol: __popcountdi2, version GCC_3.4
```

For profile `default/linux/amd64/23.0/llvm/systemd (stable)`, the symbol `__popcountdi2` is provided by `llvm-runtimes/compiler-rt` rather than `llvm-runtimes/libunwind`.
Comment 1 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2024-12-13 06:10:07 UTC
Please include emerge --info for completeness.
Comment 2 vadorovsky 2024-12-13 06:39:56 UTC
I don't know details about how the Rust binaries present in https://dev.gentoo.org/~arthurzam/ are being produced - are they by any chance the same binaries that rustup.rs is using?

Overall, I think the solution from this PR https://github.com/gentoo/gentoo/pull/39495 - treating llvm-libunwind as a drop-in replacement for GNU libunwind - is not correct. If the Rust binaries are linked against libgcc_s on a GNU environment, then they become dependent on the GNU extensions.

LLVM provides a project called llvm-libgcc (https://github.com/llvm/llvm-project/tree/main/llvm-libgcc), which is a shim layer on top of llvm-libunwind and compiler-rt which provides GNU extensions and can serve as a full replacement for libgcc_s. That's what should be used if you intend to run a binary linked against libgcc_s on GCC-free system.

I have it packaged in my personal overlay:

https://github.com/vadorovsky/overlay/tree/main/llvm-runtimes/llvm-libgcc

And I patched rust-bin in that overlay to use it:

https://github.com/vadorovsky/overlay/blob/main/dev-lang/rust-bin/rust-bin-1.82.0-r100.ebuild#L50-L52

My llvm-libgcc package allows me to use rustup.rs without any problems, I'm pretty much daily driving it for my everyday Rust usage since few months.

The reason why I didn't upstream it yet is that I feel a bit uneasy about the way that ebuild works:

https://github.com/vadorovsky/overlay/blob/main/llvm-runtimes/llvm-libgcc/llvm-libgcc-19.1.5.ebuild

It does the following:

- Builds the llvm-libgcc, which results also in building compiler-rt and llvm-libunwind from scratch, but with GNU symbols.
- Moves and patchelfs the produces artifacts into directo

It also goes a bit against the intention of LLVM upstream:

https://github.com/vadorovsky/overlay/blob/main/llvm-runtimes/llvm-libgcc/llvm-libgcc-19.1.5.ebuild#L101-L115

How upstream envisions usage of llvm-libgcc is:

- Installing the compiler-rt and llvm-libunwind artifacts, with GNU extensions, under the LLVM names.
- Symlinking libgcc.{a,so} to them.

But that approach would require us to merge llvm-runtimes/libunwind and llvm-runtimes/compiler-rt into one package.

So I'm not sure how we should proceed. I think it's about time I upstream my solution, but I'm not sure what would you prefer:

1. Keeping my hack and having the llvm-libgcc ebuild which ships a different copy of crt/libunwind.
2. Merging crt and libunwind ebuilds, adding a USE flag for adding GNU symbols, which would trigger the build with llvm-libgcc

I feel like solution 2 is more correct, but also extemely intrusive.
Comment 3 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2024-12-13 06:42:18 UTC
(In reply to vadorovsky from comment #2)
> I don't know details about how the Rust binaries present in
> https://dev.gentoo.org/~arthurzam/ are being produced - are they by any
> chance the same binaries that rustup.rs is using?
> 

rust-bin uses upstream binaries (same as rustup) except for wd40 arches where Rust supports the arch but doesn't provide binaries (tier whatever w/ host tools).
Comment 4 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2024-12-13 06:43:42 UTC
For the rest, I need to think about it, and need mgorny's input too. CCing Violet too.
Comment 5 vadorovsky 2024-12-13 06:51:20 UTC
Part of my previous comment got snipped, so to be precise - what my current llvm-libgcc ebuild does is:

- Building llvm-libgcc subproject. It produces compiler-rt and libunwind artifacts with GNU extensions.
- Installing:
  - libclang_rt.builtins*.a as libgcc.a
  - ibunwind.a as libgcc_eh.a
  - libunwind.so.1.0 as libgcc_s.so.1.0
Comment 6 matheritasiv 2024-12-13 10:32:59 UTC
Created attachment 913907 [details]
emerge --info
Comment 7 vadorovsky 2024-12-13 10:44:05 UTC
On a side note, I think that on llvm profiles (not **musl**-llvm), where GCC is present (pulled by glibc), we should keep using libgcc_s which comes from GCC.

matheritasiv's profile is llvm. libunwind was picked, because it's the first in the predicate in rust-bin:

    !llvm-libunwind? ( sys-devel/gcc:* )

In my overlay, the predicate is:

	|| (
		sys-devel/gcc:*
		llvm-runtime/llvm-libgcc
	)

https://github.com/vadorovsky/overlay/blob/main/dev-lang/rust-bin/rust-bin-1.82.0-r100.ebuild#L50-L53

Where llvm-libgcc and GCC are mutually exclusive:

https://github.com/vadorovsky/overlay/blob/main/llvm-runtimes/llvm-libgcc/llvm-libgcc-19.1.5.ebuild#L20

If we end up packaging llvm-libgcc in the Gentoo overlay, we should keep that exclusion. In practice, llvm-libgcc would be used only on musl-llvm profile. Perhaps we should even mask it globally and unmask it just in that profile.
Comment 8 vadorovsky 2024-12-13 10:46:48 UTC
In case we decide to go with the solution of merging LLVM runtimes (compiler-rt, libunwind) into one ebuild and a USE flag for GNU extensions, then that USE flag would need to trigger a conflict with GCC and perhaps allow that flag only in musl-llvm.
Comment 9 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2024-12-14 12:26:05 UTC
Maybe we should have rust-bin build a libunwind and install it to some renamed location and then patchelf to that for LLVM profiles, and file a new bug for the more extensive discussion on how to handle your suggestions (which are very much worth talking about, but IMO not something we can handle very quickly).
Comment 10 vadorovsky 2024-12-14 21:00:38 UTC
(In reply to Sam James from comment #9)
> Maybe we should have rust-bin build a libunwind and install it to some
> renamed location and then patchelf to that for LLVM profiles

If you mean building crt+libunwind with GNU extensions, then sure, that can work. I can craft a PR now.

> and file a new
> bug for the more extensive discussion on how to handle your suggestions
> (which are very much worth talking about, but IMO not something we can
> handle very quickly).

Let's move the discussion here https://bugs.gentoo.org/946486
Comment 11 rongcuid 2024-12-15 00:45:11 UTC
I encountered this exact problem on a fresh LLVM profile install.
Comment 12 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2024-12-15 01:40:48 UTC
(In reply to vadorovsky from comment #10)
> (In reply to Sam James from comment #9)
> > Maybe we should have rust-bin build a libunwind and install it to some
> > renamed location and then patchelf to that for LLVM profiles
> 
> If you mean building crt+libunwind with GNU extensions, then sure, that can
> work. I can craft a PR now.

Yes, sorry, and thanks. It's going to be a bit grotty, but I want to get rust unbricked there, then we can figure out something better. Thanks again. I'll review it as soon as I see it.
Comment 13 Larry the Git Cow gentoo-dev 2024-12-15 04:27:04 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2acf681a0ff68acd9a711fc3cb901d13a578e365

commit 2acf681a0ff68acd9a711fc3cb901d13a578e365
Author:     Sam James <sam@gentoo.org>
AuthorDate: 2024-12-15 04:26:18 +0000
Commit:     Sam James <sam@gentoo.org>
CommitDate: 2024-12-15 04:26:18 +0000

    profiles: avoid broken dev-lang/rust-bin on non-LLVM profiles
    
    Bug: https://bugs.gentoo.org/946321
    Signed-off-by: Sam James <sam@gentoo.org>

 profiles/base/package.use.mask          | 1 +
 profiles/features/llvm/package.use.mask | 1 +
 2 files changed, 2 insertions(+)
Comment 14 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2024-12-15 06:56:35 UTC
(In reply to vadorovsky from comment #2)
> Overall, I think the solution from this PR
> https://github.com/gentoo/gentoo/pull/39495 - treating llvm-libunwind as a
> drop-in replacement for GNU libunwind - is not correct. If the Rust binaries
> are linked against libgcc_s on a GNU environment, then they become dependent
> on the GNU extensions.

I'm going to revert it for now, as it's worse than the previous state. Making such users have GCC is better than having a completely broken Rust.
Comment 15 Larry the Git Cow gentoo-dev 2024-12-15 07:02:36 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=053fb81af3f45277e1869d993c240f38d0346a71

commit 053fb81af3f45277e1869d993c240f38d0346a71
Author:     Sam James <sam@gentoo.org>
AuthorDate: 2024-12-15 06:59:42 +0000
Commit:     Sam James <sam@gentoo.org>
CommitDate: 2024-12-15 07:01:52 +0000

    Revert "dev-lang/rust-bin: remove hard gcc dependency"
    
    This reverts commit 0a2e3e056ba70d19df59f2a22a44e3a53abe933e.
    
    This (clearly) doesn't work if symbols from libgcc_s are relied upon,
    like __popcountdi2. Needing sys-devel/gcc for now for rust-bin is better
    than having it entirely broken.
    
    Discussions on a broader fix are in progress on the bug.
    
    Bug: https://bugs.gentoo.org/944835
    Bug: https://bugs.gentoo.org/946321
    Signed-off-by: Sam James <sam@gentoo.org>

 dev-lang/rust-bin/rust-bin-1.71.1-r101.ebuild | 15 ++-------------
 dev-lang/rust-bin/rust-bin-1.74.1-r101.ebuild | 15 ++-------------
 dev-lang/rust-bin/rust-bin-1.75.0-r101.ebuild | 15 ++-------------
 dev-lang/rust-bin/rust-bin-1.77.1-r101.ebuild | 15 ++-------------
 dev-lang/rust-bin/rust-bin-1.79.0-r101.ebuild | 15 ++-------------
 dev-lang/rust-bin/rust-bin-1.80.1-r101.ebuild | 15 ++-------------
 dev-lang/rust-bin/rust-bin-1.81.0-r101.ebuild | 15 ++-------------
 dev-lang/rust-bin/rust-bin-1.82.0-r101.ebuild | 15 ++-------------
 8 files changed, 16 insertions(+), 104 deletions(-)
Comment 16 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2024-12-15 07:03:40 UTC
This one is fixed now, hopefully.

We can still do the workaround discussed above when it is ready and then ideally an even better fix later on again in bug 946486.
Comment 17 Jae Hak Kim 2024-12-16 10:35:25 UTC
thank you, can confirm the issue is resolved on default/linux/amd64/23.0/llvm/systemd (stable) profile.
Comment 18 vadorovsky 2024-12-27 09:14:18 UTC
(In reply to Sam James from comment #12)
> (In reply to vadorovsky from comment #10)
> > (In reply to Sam James from comment #9)
> > > Maybe we should have rust-bin build a libunwind and install it to some
> > > renamed location and then patchelf to that for LLVM profiles
> > 
> > If you mean building crt+libunwind with GNU extensions, then sure, that can
> > work. I can craft a PR now.
> 
> Yes, sorry, and thanks. It's going to be a bit grotty, but I want to get
> rust unbricked there, then we can figure out something better. Thanks again.
> I'll review it as soon as I see it.

https://github.com/gentoo/gentoo/pull/39859

Sorry for doing it so late. It took me time to get familiar with all the LLVM and cmake eclasses and make a decision what to use. At the end I figured out that just using the cmake eclass is probably the best here.

Overall it's still hacky and messy, but I hope still acceptable as a temporary workaround.
Comment 19 vadorovsky 2024-12-27 11:18:18 UTC
(In reply to vadorovsky from comment #18)
> https://github.com/gentoo/gentoo/pull/39859
> 
> Sorry for doing it so late. It took me time to get familiar with all the
> LLVM and cmake eclasses and make a decision what to use. At the end I
> figured out that just using the cmake eclass is probably the best here.
> 
> Overall it's still hacky and messy, but I hope still acceptable as a
> temporary workaround.

Meh, the ebuild itself works with that patch and all Rust binaries (rustc, cargo etc.) are linked against the custom libunwind (installed in /opt), but as soon as I'm trying to use that toolchain for building some bigger ebuilds (e.g. app-editors/helix), it fails with:

ld.lld: error: unable to find library -libgcc_s

Because Rust itself puts -lgcc into linker flags.

I could try to work around that by installing the library as /opt/rust*/lib/runtime/libgcc_s.so and injecting that directory into RUSTFLAGS, but that would require providing custom RUSTFLAGS via make.defaults in LLVM profiles. And honestly, at this point, I'm doubting whether it makes sense to go into such messy workaround at all. I think I would rather spend my time on the proper solution (#946486). It will take time, but I'm fine with that. It looks like the workaround might take even more time.
Comment 20 vadorovsky 2024-12-27 18:20:38 UTC
I closed the workaround PR. Let's get #946486 rolling.