-
Notifications
You must be signed in to change notification settings - Fork 6
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
Linking fails on nightly rustc due to mismatched ABI flags #9
Comments
ayrtonm
changed the title
Linking fails on nightly rustc
Linking fails on nightly rustc due to mismatched ABI flags
May 1, 2022
ayrtonm
added a commit
to ayrtonm/rust
that referenced
this issue
May 11, 2022
In rust-lang#95604 the compiler started generating a temporary symbols.o which is added to the linker invocation. This object file has an `e_flags` which may be invalid for 32-bit MIPS targets. Even though symbols.o doesn't contain code, linking with [lld fails](https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/MipsArchTree.cpp#L79) with ``` rust-lld: error: foo-cgu.0.rcgu.o: ABI 'o32' is incompatible with target ABI 'n64' ``` because it omits the ABI bits (EF_MIPS_ABI_O32) so lld assumes it's using the N64 ABI. This breaks linking on nightly for the out-of-tree [psx target](ayrtonm/psx-sdk-rs#9), the builtin mipsel-sony-psp target (cc @overdrivenpotato) and any other 32-bit MIPS target using lld. This PR sets the ABI in `e_flags` to O32 since that's the only ABI for 32-bit MIPS that LLVM supports. It also sets other `e_flags` bits based on the target. I had to bump the object crate version since some of these constants were [added recently](gimli-rs/object#433). I'm not sure if this PR needs a test, but I can confirm that it fixes the linking issue on both targets I mentioned.
bors
added a commit
to rust-lang-ci/rust
that referenced
this issue
May 13, 2022
Fix e_flags for 32-bit MIPS targets in generated object file In rust-lang#95604 the compiler started generating a temporary symbols.o which is added to the linker invocation. This object file has an `e_flags` which is invalid for 32-bit MIPS targets. Even though symbols.o doesn't contain code, linking these targets with [lld fails](https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/MipsArchTree.cpp#L76-L79) with ``` rust-lld: error: foo-cgu.0.rcgu.o: ABI 'o32' is incompatible with target ABI 'n64' ``` because it omits the ABI bits (`EF_MIPS_ABI_O32`) so lld assumes it's using the N64 ABI. This breaks linking on nightly for the out-of-tree [mipsel-sony-psx target](ayrtonm/psx-sdk-rs#9), the builtin mipsel-sony-psp target (cc `@overdrivenpotato)` and probably any other 32-bit MIPS target using lld. This PR sets the ABI in `e_flags` to O32 since that's the only ABI for 32-bit MIPS that LLVM supports. It also sets other `e_flags` bits based on the target to avoid similar issues with the object file arch and PIC. I had to bump the object crate version since some of these constants were [added recently](gimli-rs/object#433). I'm not sure if this PR needs a test, but I can confirm that it fixes the linking issue on both targets I mentioned.
Closed by rust-lang/rust#96930 |
xSetech
added a commit
to xSetech/rust
that referenced
this issue
Jul 9, 2023
PR rust-lang#95604 introduced a "synthetic object file to ensure all exported and used symbols participate in the linking". One constraint on this file is that for MIPS-based targets, its architecture-specific ELF flags must be the same as all other object files passed to the linker. That's enforced by LLD, here: https://github.com/llvm/llvm-project/blob/llvmorg-16.0.6/lld/ELF/Arch/MipsArchTree.cpp#L77 The current approach to determining e_flags for 32-bit was implemented in PR rust-lang#96930, which links to this issue that summarizes the problem well: ayrtonm/psx-sdk-rs#9 > ... the temporary object file is created with an e_flags which is > invalid for 32-bit MIPS targets. The main issue is that it omits the ABI > bits (EF_MIPS_ABI_O32) which implies it uses the N64 ABI. To enable the N32 MIPS ABI (which succeeded O32), this patch enables setting the synthetic object's ABI based on the target "llvm-abiname" field, if it's given; otherwise, the O32 ABI is assumed for 32-bit MIPS targets. More information about the N32 ABI can be found here: https://web.archive.org/web/20160121005457/http://techpubs.sgi.com/library/manuals/2000/007-2816-005/pdf/007-2816-005.pdf
matthiaskrgr
added a commit
to matthiaskrgr/rust
that referenced
this issue
Jul 11, 2023
Support explicit 32-bit MIPS ABI for the synthetic object PR rust-lang#95604 introduced a "synthetic object file to ensure all exported and used symbols participate in the linking". One constraint on this file is that for MIPS-based targets, its architecture-specific ELF flags must be the same as all other object files passed to the linker. That's enforced by LLD, here: https://github.com/llvm/llvm-project/blob/llvmorg-16.0.6/lld/ELF/Arch/MipsArchTree.cpp#L77 The current approach to determining e_flags for 32-bit was implemented in PR rust-lang#96930, which links to this issue that summarizes the problem well: ayrtonm/psx-sdk-rs#9 > ... the temporary object file is created with an e_flags which is > invalid for 32-bit MIPS targets. The main issue is that it omits the ABI > bits (EF_MIPS_ABI_O32) which implies it uses the N64 ABI. To enable the N32 MIPS ABI (which succeeded O32), this patch enables setting the synthetic object's ABI based on the target "llvm-abiname" field, if it's given; otherwise, the O32 ABI is assumed for 32-bit MIPS targets. More information about the N32 ABI can be found here: https://web.archive.org/web/20160121005457/http://techpubs.sgi.com/library/manuals/2000/007-2816-005/pdf/007-2816-005.pdf
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Since upstream LLVM now supports load delay slots, I tried updating the rustc patch in this repo. I was able to build nightly rustc, but it's unusable since all builds fail with the following linker error.
This issue occurs on nightly rustc for both the psx and psp (@sajattack) targets and is likely an issue for other 32-bit MIPS targets.
This is caused by a recent change that adds a temporary
symbols.o
to the linker invocation. The change itself is fine, but the temporary object file is created with ane_flags
which is invalid for 32-bit MIPS targets. The main issue is that it omits the ABI bits (EF_MIPS_ABI_O32
) which implies it uses the N64 ABI. Even thoughsymbols.o
doesn't contain code, lld fails since the ABI bits in all files don't match.The fix is pretty straightforward and I have a patch to determine
e_flags
from the target options, but theobject
crate is missing some ABI constants so it needs to be updated first.The text was updated successfully, but these errors were encountered: