Repository navigation
fix(relinker): rewrite XSAVEOPT to XSAVE under --to-rosetta - #7918
Conversation
|
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.
|
d940bfd to
0c93987
Compare
|
Rebase handoff — rebased onto current Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release, To pick it up: Head is |
XSAVEOPT raises an illegal instruction under Rosetta on an M5 running macOS 27.0.1, as XSAVEC does, while XSAVE and XRSTOR save and restore x87, SSE and AVX state in the standard format. The PS5's Zen 2 has XSAVEOPT, so code built for it can use the instruction without a CPUID check. XSAVEOPT differs from XSAVE only in the init and modified optimizations: it may skip writing state that is in its initial configuration or unchanged since the last XRSTOR from the same area. XRSTOR restores the same state from the area XSAVE writes, so --to-rosetta rewrites XSAVEOPT (NP 0F AE /6, memory operand) to XSAVE (/4) in place, keeping the prefixes and the operand, as RDSEED becomes RDRAND. CLWB (66 0F AE /6), MFENCE, UMONITOR, UMWAIT and the Intel target are left alone. XSAVEC is not converted: it writes the compacted format. The converter tests check the rewrite for the plain, REX.W, RSP-relative, extended-base, RIP-relative and FS-relative forms, check that the neighbouring 0F AE encodings are not taken, and execute the rewritten XSAVEOPT64 followed by XRSTOR on YMM3 in the x86-64 build. The --to-rosetta integration test now covers XSAVEOPT as well.
0c93987 to
ce6c2a0
Compare
|
Checked the XSAVEOPT decoder (66 = CLWB, F3 = CLRSSBSY, F2 and the register form are left alone), the ModRM rewrite |
What
XSAVEOPT raises an illegal instruction under Rosetta. The PS5's Zen 2 has it, so code built for the console can use it without a CPUID check. With
--to-rosettait is now rewritten to XSAVE in place:0F AE /6with a memory operand becomes0F AE /4, keeping the prefixes, REX and operand, the same way RDSEED becomes RDRAND.XSAVEOPT differs from XSAVE only in the init and modified optimizations (Intel SDM volume 1, chapter 13). They let it skip writing state that is in its initial configuration or unchanged since the last XRSTOR from the same area. XSAVE writes the same XSTATE_BV and the full state, so XRSTOR restores the same registers from either area.
Not taken: CLWB (
66 0F AE /6, already a NOP), MFENCE, UMONITOR, UMWAIT, XSAVE, XRSTOR, CLFLUSH. The Intel target and a plain relink are unchanged. XSAVEC also faults under Rosetta but is not converted, because it writes the compacted format. The debt entry says so.Changes:
DecodedInstruction::IsXsaveopt, theXSAVEOPTtable entry, and the in-place case in_matchRosetta.Amd64OnlyConverterTests: rewrite checks for the plain, REX.W, RSP-relative, r12-based, RIP-relative and FS-relative forms; the neighbouring0F AEencodings are not taken; not converted for Intel. NewxsaveoptExecutionruns the rewritten XSAVEOPT64, clears YMM3, runs XRSTOR and checks YMM3, XSTATE_BV and the standard-format offsets. It runs on x86-64 Linux and macOS hosts and is empty elsewhere.test_to_rosetta.pynow includes XSAVEOPT in the relinked fixture.docs/user/USAGE.md(--to-rosettarow) and a new entry indocs/dev/debt/relinker.md.Tested
Apple M5, macOS 27.0.1 (26A434), Apple clang, relinker-only Release build.
Under Rosetta, from a standalone
clang -arch x86_64program (sysctl.proc_translated= 1) that runs the bytes from executable memory:Same host: XSAVEC also raises SIGILL. XSAVE64 with RFBM 7 followed by XRSTOR64 restores YMM3, XSTATE_BV reads 7, and the AVX high half is at offset 576. XGETBV reads XCR0 = 7 and CPUID (0xD, 0) gives 832 bytes, but CPUID leaf 1 reports neither XSAVE nor OSXSAVE, and leaf (0xD, 1) reports neither XSAVEOPT nor XSAVEC.
ctest, 207/207 pass.-DCMAKE_OSX_ARCHITECTURES=x86_64), wherexsaveoptExecutionactually runs: 207/207 pass, includingamd64_only_converterandto_rosetta.amd64_only_converterfails withXSAVEOPT was not rewritten to XSAVE.python3 tools/check_conventions.py --base origin/mainandgit diff --checkpass.Not tested on Linux or Windows. The execution test is also built for x86-64 Linux, so the Linux CI job runs it natively. No title was tested, and I don't know of one that uses XSAVEOPT.
No open PR or issue covers XSAVEOPT or XSAVEC. This branch is rebased on main after #6111.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)