Skip to content

fix(relinker): report processor 0 from RDTSCP under --to-rosetta - #6111

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
Kernel-Hunter:fix/rosetta-rdtscp-processor
Oct 18, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
Kernel-Hunter:fix/rosetta-rdtscp-processor

Conversation

@Kernel-Hunter

Copy link
Copy Markdown
Contributor

What

Under Rosetta, RDTSCP loads ECX with Rosetta's constant TSC_AUX, 0xAAAAAAAB, which is not a processor index. --to-rosetta already lowers RDPID to processor 0 for this reason, and docs/dev/debt/relinker.md lists RDTSCP's ECX as not converted. So the same program could read processor 0 through RDPID and 0xAAAAAAAB through RDTSCP.

With --to-rosetta, RDTSCP (0F 01 F9, no 66/F2/F3 prefix) now goes through an optional out-of-line stub, the same mechanism RDPID uses. The stub runs the original RDTSCP, so EDX:EAX and the instruction's ordering stay the same, then does mov ecx, 0 (B9 00 00 00 00). That clears all of RCX and leaves the flags alone. As with RDPID, a site that has no movable instruction after it for the jump is kept, and a kept RDTSCP still reports Rosetta's value. The Intel target and a plain relink do not change.

Changes:

  • DecodedInstruction::IsRdtscp, the RDTSCP table entry, and the matcher cases in _matchRosetta, _emitOutOfLine and MatchSequence, which marks a sequence that starts with RDTSCP as optional, as it does for RDPID.
  • Amd64OnlyConverterTests: matcher cases (Rosetta stub bytes, optional, not converted for Intel, SWAPGS 0F 01 F8 and 66 0F 01 F9 left alone), plus rdtscpExecution. That test runs the stub on x86-64 Linux and macOS hosts and checks that RCX is 0, the counter is not 0 and CF is preserved. On other hosts it is empty.
  • The --to-rosetta entries in docs/dev/debt/relinker.md and docs/user/USAGE.md.

Tested

Apple M5 (MacBook Air), macOS 27.0.1 (26A434), Apple clang 21.0.0, CMake 4.4.4, Ninja 1.13.2.

Rosetta's value, from a standalone x86-64 program built with clang -arch x86_64 and run under Rosetta: RDTSCP returns ECX = 0xaaaaaaab. RDPID ends in SIGILL, which is why it is already lowered.

Relinker-only build, native arm64 (cmake -S . -B build-relinker -G Ninja -DCMAKE_BUILD_TYPE=Release -DANYPS5_RELINKER_ONLY=ON -DBUILD_TESTING=ON):

  • ctest --test-dir build-relinker -j8 --timeout 30: 163 of 163 pass.
  • Without the source change, the new amd64_only_converter cases fail with RDTSCP was not lowered through an optional stub.

Relinker-only build as x86-64 under Rosetta (same configure plus -DCMAKE_OSX_ARCHITECTURES=x86_64, Python 3 run as x86-64), so that rdtscpExecution really runs the stub:

  • amd64_only_converter, to_rosetta and macos_output pass.
  • Without the source change, the execution case alone fails with RDTSCP stub was not produced.
  • 159 of 163 pass overall. The other 4 (pr_overlap_encoding, stubgen_stdout_newlines, release_package, linux_fixed_base) also fail on main in this setup, because the only x86-64 Python here is the system 3.9, which lacks zip(strict=) and write_text(newline=).

End to end under Rosetta: a byte-built PS5-style ELF (a copy of the macos/import_fixture.py layout) runs rdtscp, then exit(ecx != 0). I relinked it with --macos --skip-sce-module and ran it with two small x86-64 stub dylibs standing in for libc.prx and libkernel.prx. Exit code 1 with main's relinker, both with and without --to-rosetta. Exit code 0 with this branch and --to-rosetta.

python3 tools/check_conventions.py --base origin/main and git diff --check pass. I did not build or run anything on Linux or Windows; the execution test is compiled for x86-64 Linux too, so the Linux CI job runs it. No title was tested.

tools/pr_overlap.py lists text overlap only, not the same function: #5784 (ANDN) touches the same _matchRosetta lines and the same line in relinker.md and USAGE.md, and #5683 and #5762 add calls at the same place in the converter test's main. Whichever merges second needs a small rebase.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes, written with AI assistance. Tested as described above.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 7173 core/relinker/codegen/src/x86/Amd64OnlyInstructionMatcher.cpp L270
PR 7531 core/relinker/codegen/src/x86/Amd64OnlyInstructionMatcher.cpp L270

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 2780 core/relinker/codegen/include/codegen/x86/Amd64OnlySubstitutionTable.hpp
core/relinker/codegen/src/x86/Amd64OnlyInstructionMatcher.cpp
core/relinker/codegen/tests/Amd64OnlyConverterTests.cpp
PR 3998 docs/user/USAGE.md
PR 4891 docs/user/USAGE.md
PR 5021 docs/dev/debt/relinker.md
docs/user/USAGE.md
PR 5925 docs/user/USAGE.md
PR 6314 docs/user/USAGE.md
PR 6354 docs/dev/debt/relinker.md
PR 6788 docs/user/USAGE.md
PR 6977 docs/dev/debt/relinker.md

This was referenced Oct 15, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 15, 2026
@Kernel-Hunter
Kernel-Hunter force-pushed the fix/rosetta-rdtscp-processor branch from c690012 to e097ea1 Compare October 15, 2026 19:30
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 15, 2026
@adriadam10 adriadam10 self-assigned this Oct 16, 2026
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the RDTSCP decoder (prefix/REX handling, 0F 01 F8 SWAPGS and 66-prefixed forms are left alone), the stub order (original RDTSCP, then mov ecx, 0, which keeps the flags) and the optional-site handling against RDPID. amd64_only_converter, relinker_conversion, relinker_executables and to_rosetta pass on the PR merged onto main, including rdtscpExecution on x86-64 Linux (RCX = 0, counter non-zero, CF preserved). Rosetta-hardware behaviour rests on your M5 run. Merging.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 17, 2026
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 17, 2026
…CP under --to-rosetta (@Kernel-Hunter)

Open upstream PR that adds macOS behaviour this branch did not have. The only conflict was a list both sides appended to (a debt index or the relinker test registrations), so both entries are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 17, 2026
Merging boykopovar#6111 kept both versions of the --to-rosetta entry. The base's version carries the M1 and M5 instruction measurements; the PR's records that RDTSCP now reports processor 0 and which sites are kept. They are now one entry with both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Kernel-Hunter
Kernel-Hunter force-pushed the fix/rosetta-rdtscp-processor branch from e097ea1 to c8f5264 Compare October 17, 2026 20:06
@Kernel-Hunter

Copy link
Copy Markdown
Contributor Author

Thanks for checking it. Rebased onto main again: the RDTSCP sentence in docs/dev/debt/relinker.md conflicted with the new macOS 26.4 measurements, so I kept those and changed only the RDPID/RDTSCP part. Relinker tests pass locally (178/178) and the conventions check is clean.

@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Oct 17, 2026
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 18, 2026
…CP under --to-rosetta (@Kernel-Hunter)

Open upstream PR that adds macOS behaviour this branch did not have. The only conflict was a list both sides appended to (a debt index or the relinker test registrations), so both entries are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 18, 2026
Merging boykopovar#6111 kept both versions of the --to-rosetta entry. The base's version carries the M1 and M5 instruction measurements; the PR's records that RDTSCP now reports processor 0 and which sites are kept. They are now one entry with both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 18, 2026
…tta (@MarcZX100)

Brings the Rosetta ADX lowering from the open upstream pull request into the fork's main ahead of its review. It and the fork's RDTSCP lowering (boykopovar#6111) each add a Rosetta case at the same point of the AMD64-only matcher; both are kept, RDTSCP first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rosetta sets RDTSCP's ECX to its constant TSC_AUX, 0xAAAAAAAB, which is
not a processor index. --to-rosetta already makes RDPID return processor
0 for the same reason, so code reading the processor through RDTSCP saw
a different value from code reading it through RDPID.

--to-rosetta now moves RDTSCP into an optional stub that runs the
instruction unchanged and then loads 0 into ECX with a MOV, which
leaves the counter in EDX:EAX and the flags as they were. A site with no
movable instruction after it for the jump is kept, as for RDPID. The
Intel target and a plain relink are unchanged.
@adriadam10
adriadam10 force-pushed the fix/rosetta-rdtscp-processor branch from c8f5264 to 57e52c1 Compare October 18, 2026 16:29
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
@adriadam10
adriadam10 merged commit f890e21 into boykopovar:main Oct 18, 2026
8 checks passed
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 18, 2026
Keeps the macOS port current with 117 upstream commits. Upstream took boykopovar#6111's RDTSCP lowering; the AMD64-only matcher keeps it and the fork's ADCX/ADOX case (boykopovar#7173) after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ycarogabriel-lgtm added a commit to ycarogabriel-lgtm/AnyPS5 that referenced this pull request Oct 18, 2026
Brings the pull request up to the 117 upstream commits that made it conflict. Upstream took boykopovar#6111's RDTSCP lowering; the AMD64-only matcher keeps it and the ADCX/ADOX case from boykopovar#7173 after it, as on the fork's main, where the suites passed with this merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants