-
Notifications
You must be signed in to change notification settings - Fork 22
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
Linux/x64: Fix SIMD routines not linking due to illegal relocations #1367
base: main
Are you sure you want to change the base?
Conversation
Rav1d uses the assembly routines from dav1d. Have you tested if this is also an issue for dav1d? Is this We'd like to keep using the same assembly routines. |
I use mold, too, for development and have never seen this error. That's odd, what exactly are you doing differently? |
This is not an issue with
If there is in fact a way to do such a thing in Rust, then we could avoid modifying the assembly at all indeed. See my original message in this thread, and the detailed explanation in rerun-io#3 (comment).
No, this is not specific to any linker. AFAIU it all comes down to how position-independent executables, ASLR, 32bit relocations and load-time/run-time symbol interposition all interact in arcane, annoying ways on Linux/x64. Here's stock
|
This isn't specific to This will fail to link for any position-independent executable (i.e. all Linux/x64 Rust executables by default) that makes actual use of any of the problematic symbols (i.e. the SIMD-optimized routines that rely on the tables in It's pretty hard/annoying to minimally reproduce as you need to link to all the right symbols and generate the right 32bit relocations at the right place and time. If you're on 64bit linux, you shoud be able to repro using:
|
Sorry, I'm just confused why we have not seen this error before when building the |
Also, do you know if there's any effort to get hidden visibility or ELF symbol visibility as a whole into Rust? That would be the best solution if it existed. I think your solution is quite good, and the asm changes are pretty unobtrusive, so upstreaming future asm changes should be pretty simple with this. But I'm still trying to understand why this is an issue for you and not for us when we build the |
The problem is certainly known in multiple forms:
David Lattimore has a great blog post on the matter, which covers how finicky and hard to reason about all of this is. As far as I know, the Most things related to these matters are very poorly documented, if at all. It is very possible that a solution exists out there somewhere, but I'm not aware of it.
All of this is extremely finicky, filled with corner cases and weird interactions, even depends on the order you build things in. See blog post above for a taste. I don't understand any of it enough to be able to create a minimal reproduction, the best I have is the Rerun codebase. In this specific case, you need to hit the right order for |
Hi @teh-cmc! I believe we did run into the same issue in #1322 when we tried to support building |
I wish someone would come up with something nicer, but if not... then yeah, sounds good to me. 👍 |
Maybe this could help: rust-lang/rust#118417? But it's not per symbol. |
On linux/x64, if using any of the assembly SIMD routines that rely on the tables defined in
tables.rs
,rav1d
will fail to link with the following errors:Long story short, the reason this fails is because these tables are exposed publicly in the final ELF artifact, when they shouldn't be.
The C implementation avoids this problem by making use of compiler intrinsincs:
rav1d/src/tables.h
Lines 113 to 115 in c7d127e
where
EXTERN
is defined as:rav1d/include/common/attributes.h
Lines 116 to 120 in c7d127e
As far as I know, there doesn't exist any way of modifying the ELF visibility of Rust symbols directly from code.
Therefore, the best approach I have found is to modify the assembly itself in order to hide these extern references directly, and then the linker gets the hint.
For a long-winded, much more in depth explanation, see: