Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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
Contributor

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
Collaborator

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
Collaborator

bors commented May 13, 2022

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

@bors
Copy link
Collaborator

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
# for free to join this conversation on GitHub. Already have an account? # 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