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

Fix e_flags for 32-bit MIPS targets in generated object file #96930

Merged
merged 1 commit into from
May 13, 2022

Conversation

ayrtonm
Copy link
Contributor

@ayrtonm ayrtonm commented May 11, 2022

In #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 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, 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. 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.

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.
@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 11, 2022
@rust-highfive
Copy link
Collaborator

r? @petrochenkov

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 11, 2022
@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 12, 2022
@petrochenkov
Copy link
Contributor

Thanks!
@bors r+

If this doesn't get into 1.61 beta in time please ping me and we'll backport this.

@bors
Copy link
Contributor

bors commented May 13, 2022

📌 Commit 3d5b1ee has been approved by petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 13, 2022
@bors
Copy link
Contributor

bors commented May 13, 2022

⌛ Testing commit 3d5b1ee with merge 1c80ac0...

@bors
Copy link
Contributor

bors commented May 13, 2022

☀️ Test successful - checks-actions
Approved by: petrochenkov
Pushing 1c80ac0 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label May 13, 2022
@bors bors merged commit 1c80ac0 into rust-lang:master May 13, 2022
@rustbot rustbot added this to the 1.62.0 milestone May 13, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (1c80ac0): comparison url.

Summary: This benchmark run did not return any relevant results.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

@Mark-Simulacrum
Copy link
Member

@petrochenkov This PR landed in 1.62 -- was there a separate PR that should be landing in 1.61 beta?

@petrochenkov
Copy link
Contributor

@Mark-Simulacrum
Sorry, 1.61 is a +/-1 error from my side, Beta 1.61 turns into stable on May 19 2022, not into beta.

The important part is to land this PR into the same release as #95604, because it fixes a regression introduced by it.
So apparently there's no need for a backport.

@ayrtonm ayrtonm deleted the mips32-tmp-file branch June 5, 2022 01:07
xSetech added a commit to xSetech/rust that referenced this pull request 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 pull request 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
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants