Skip to content

Set EF_MIPS_CPIC on static MIPS targets that use abicalls - #161485

Closed
ItsNoHax wants to merge 2 commits into
rust-lang:mainfrom
ItsNoHax:mips-cpic-static-abicalls
Closed

ItsNoHax wants to merge 2 commits into
rust-lang:mainfrom
ItsNoHax:mips-cpic-static-abicalls

Conversation

@ItsNoHax

@ItsNoHax ItsNoHax commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

rustc synthesizes some object files with the object crate rather than with LLVM — crate metadata, and the symbols.o it hands to the linker — so their MIPS ELF header flags are computed by hand in elf_e_flags. EF_MIPS_CPIC was set only when the relocation model was not static.

LLVM keys EF_MIPS_CPIC off abicalls, not off the relocation model: it sets the flag on every object it emits unless the target selects +noabicalls. So a static target that leaves abicalls enabled gets LLVM objects marked CPIC and rustc's own objects not, and lld warns once per object:

rust-lld: .../libpsp-....rlib(psp-....rcgu.o): linking abicalls code with non-abicalls code .../symbols.o

Measured on mipsel-sony-psp: every LLVM object is 0x10001005 (noreorder|cpic|o32|mips2) while symbols.o and lib.rmeta are 0x10001000. A hello-world picks up 60 such warnings — now visible via the linker_messages lint. Reported downstream as overdrivenpotato/rust-psp#203.

This is precisely the "static object with dynamic calls" case the existing comment in this function describes, so the fix sets CPIC (without PIC) for it, matching LLVM.

Affected targets

Only static MIPS targets whose spec omits +noabicalls: mipsel-sony-psp and mipsel-sony-psx. Targets that are not static are untouched, and mipsel-unknown-none (which sets +noabicalls) keeps getting no CPIC — the added test pins both directions.

Verification

I have not built a patched compiler, so I verified the change by reproducing its exact effect: taking rustc's own symbols.o from a real build, setting the CPIC bit, and re-running rustc's exact rust-lld invocation.

before after
abicalls warnings (ci/tests) 65 0

Combined with #161484, a cargo psp build of rust-psp's test suite goes from 130 linker warnings to 0, and the suite still passes on PPSSPP (47 pass / 0 fail, FINAL_SUCCESS).

The new tests/run-make/mips-cpic-e-flags checks lib.rmeta inside the rlib, which is the member rustc builds itself. I confirmed by hand that it is 0x10001000 today, i.e. the test does fail without the change. Note that the test itself has not been executed (I could not build the compiler locally), so please give the run_make_support usage a careful look.

@rustbot rustbot added A-run-make Area: port run-make Makefiles to rmake.rs S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 21, 2026
@rustbot

rustbot commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust Project has assigned @TaKO8Ki (or someone else) to review your changes, you should hear from them (or someone else) within the next two weeks.

Please see the contribution instructions and our LLM policy for more information.

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 75 candidates
  • Random selection from 21 candidates

@ItsNoHax

ItsNoHax commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor Author

@TaKO8Ki This is LLM assisted, not able to edit the label now. Logic is solid and verified.

@ItsNoHax

Copy link
Copy Markdown
Contributor Author

CI caught a bug in the test, not in the change — and in doing so confirmed the change works.

run_make_support::llvm_readobj() sets --elf-output-style GNU in its constructor, and the GNU style spells this flag cpic rather than EF_MIPS_CPIC, so the assertion could never match. I'd checked the needle against the raw llvm-readobj binary, which defaults to the LLVM style. Fixed by asking for the LLVM style explicitly.

The useful part is what the failing assertion dumped for mipsel-sony-psp on a stage2 build with this patch applied:

Flags:                             0x10001004, cpic, o32, mips2

That is the metadata object carrying EF_MIPS_CPIC, which is exactly what the change is meant to do — it was 0x10001000 before. So the compiler side is confirmed on real rustc; only the assertion was looking for the wrong spelling.

rustc synthesizes some object files with the `object` crate rather than with
LLVM -- crate metadata, and the `symbols.o` handed to the linker -- so their
MIPS ELF header flags are computed by hand. `EF_MIPS_CPIC` was set only when
the relocation model was not `static`.

LLVM, however, keys `EF_MIPS_CPIC` off abicalls, not off the relocation model:
it sets the flag on every object it emits unless the target selects
`+noabicalls`. A static target that leaves abicalls enabled -- `mipsel-sony-psp`
and `mipsel-sony-psx` -- therefore ends up with LLVM objects marked CPIC and
rustc's own objects not, and lld warns "linking abicalls code with non-abicalls
code" once per object.

That is exactly the "static object with dynamic calls" case the existing
comment describes, so set CPIC (without PIC) for it and match LLVM.
Checks `lib.rmeta`, which is the archive member rustc builds itself with the
`object` crate, on the two static MIPS targets that leave abicalls enabled and
on `mipsel-unknown-none`, which does not, so that the new branch cannot fire
where LLVM would not have set the flag either.
@ItsNoHax
ItsNoHax force-pushed the mips-cpic-static-abicalls branch from 5bcab92 to 4bfb234 Compare August 21, 2026 21:52
@TaKO8Ki TaKO8Ki added the llm-assisted An LLM-assisted PR as defined by the LLM policy. Requires ahead-of-time consent by assignee. label Aug 29, 2026
@ItsNoHax

Copy link
Copy Markdown
Contributor Author

Let me know if you want any changes made @TaKO8Ki.

@hanna-kruppe

hanna-kruppe commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Hi, I'm going to close this PR as it has several problems w.r.t. our LLM usage policy. You are welcome to open additional PRs as long as they follow our policy. Note in particular:

  • As previously explained, it is not enough to disclose that an LLM was used, we need to actually know how it was used
  • Which uses of LLMs are banned even if disclosed, including writing Github comments, PR descriptions, commit messages, or substantial comments in the code.
  • Our guidelines for using LLMs to contribute

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 14, 2026
@ItsNoHax

Copy link
Copy Markdown
Contributor Author

That's fair @hanna-kruppe. I'll clean it up later, make sure it complies with the LLM usage policy and create a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-run-make Area: port run-make Makefiles to rmake.rs llm-assisted An LLM-assisted PR as defined by the LLM policy. Requires ahead-of-time consent by assignee. 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.

4 participants