Repository navigation
fix(relinker): convert stack-guard and thread-pointer reads with an empty PT_TLS for macOS - #6448
Conversation
…mpty PT_TLS for macOS
…empty PT_TLS for macOS
|
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.
|
jotitadev
left a comment
There was a problem hiding this comment.
Tested on macOS, which the description lists as not run.
Machine: Apple M2 Max, macOS 27.2, Xcode 27, Rosetta 2. Head 14fb570 merged onto main 03c4cb5, relinker-only build (-DANYPS5_RELINKER_ONLY=ON -DBUILD_TESTING=ON), Release.
- arm64: 174/174 pass, including
macos_empty_tls. - x86_64 under Rosetta with
/usr/bin/python3(3.9.6): 171/174. The 3 failures (pr_overlap_tools,release_package,linux_fixed_base) fail the same way onmain03c4cb5 and are unrelated to this change. test_macos_empty_tls.pywithmain's relinker fails onempty-guardwithGuest TLS access without a non-empty PT_TLS, so the test covers the regression.
Runtime with a block of size 0: main does not have the macOS guest TLS runtime yet, so I used GuestTlsMacOs.cpp from mugurc's macos-port branch (b7eb6b6). I built it as an x86_64 libs/libkernel.prx, with a small Aps5StartGuest_nid_no_patch that calls the guest entry and prints rax. Then I converted the test's empty-guard and empty-thread-pointer images with this PR's relinker (--macos --skip-sce-module) and ran both under Rosetta:
Aps5GuestTlsRegisteraccepts the descriptor (version 1, template 0, block 0, alignment 1).Aps5GuestTlsAllocateallocates only the thread control block.%fs:0returns a thread pointer that points at itself (rax=0x7fa315704c80,*rax=0x7fa315704c80).%fs:0x28returns 0, the zeroed stack guard slot of the new TCB.- Both exit 0.
So the macOS runtime handles the empty block as expected. I did not test with real titles; I don't have ccleste, Dusklight or Wind Waker.
Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.
|
Hardware run on Apple silicon. macOS 26.7.1, Apple M2 (8 GB), Rosetta 2, AppleClang 21.0.0. Relinkers built (
AI-assisted: yes |
…rt stack-guard and thread-pointer reads with an empty PT_TLS for macOS (@DavidSamir) Taken from the open upstream pull request so the macOS integration branch carries every piece of the port that is already under review, instead of re-implementing it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Retest on
Nothing past the first stop is tested. The run libraries are the macOS port series from 2026-10-12, as current AI-assisted: yes (Claude Code) |
|
Re-checked against current main: the merge is clean, the one-line change in |
What
Four catalog titles cannot be converted for macOS on
main: ccleste (PPSA59322), Mortalfin (PPSA99141), Dusklight (PPSA99305) and Wind Waker (PPSA99309).Each has a
PT_TLSwith file and memory size 0 (alignment 1) and reads the stack guard at%fs:0x28. This is the case #1911 fixed for Windows output, with ccleste as its title: the guard (%fs:0x28) and the thread pointer (%fs:0) live in the thread control block, not in the TLS block. The macOS writer inMacOsImage.cpptreats a module as having TLS only whenPT_TLSis non-empty, and refuses any access otherwise.An empty
PT_TLSwith accesses now takes the normal TLS path, as on Windows: the descriptor describes a block of size 0, and the existing displacement check still refuses every read into thread-local data, because a block of size 0 has none. An emptyPT_TLSwithout accesses still gets no descriptor, and a module withoutPT_TLSis refused as before.Four commits:
fix(relinker): convert stack-guard and thread-pointer reads with an empty PT_TLS for macOS.test(relinker): convert stack-guard and thread-pointer reads with an empty PT_TLS for macOS: a newmacos_empty_tlstest converts both reads with an emptyPT_TLSand checks the access is gone and the descriptor has template and block size 0.test(relinker): keep refusing thread-local data reads with an empty PT_TLS for macOS:%fs:-8fails withis not in the thread TLS block.test(relinker): give an empty PT_TLS without accesses no macOS TLS descriptor.Tested
Windows host (14fb570 on
main0afa6a6, Windows 11 10.0.26300, WinLibs GCC 15.2.0 r7, Release). The relinker writes macOS output on any host:tools/check_conventions.py --base origin/main: passed.tools/pr_overlap.py: no overlap with open pull requests.-DANYPS5_RELINKER_ONLY=ON -DBUILD_TESTING=ON), the relinker builds at each of the four commits and every test that runs passes. The 27 that fail are the same at every commit and come from that build: 25 test programs it does not compile,windows_diagnostic_fixture_isolation, which copies one of them, andcheck_main_sync, which reads git's UTF-8 output as cp1252 on this host (sp ace é.txt) and fails the same way onmain. The change is inMacOsImage.cpp, which only the relinker links, so the relinker-only build runs every test that can see it.macos_empty_tlsfails without the fix: withmain's relinker,empty-guardstops withGuest TLS access without a non-empty PT_TLS.macos|tlstests pass (guest_force_tls_destructoris not run because only the relinker target was built).main's relinker against this branch's, same arguments: ccleste (PPSA59322), Dusklight (PPSA99305) and Wind Waker (PPSA99309) now convert, and the other 76 outputs are byte-identical. Mortalfin (PPSA99141) stops first on the refusal fix(relinker): skip prefixed decodings inside an earlier instruction in the macOS TLS scan #6410 removes, and Morrowind (PPSA99630) on the one fix(relinker): rewrite ALU reads of guest TLS through %fs in macOS output #6419 removes; with fix(relinker): skip prefixed decodings inside an earlier instruction in the macOS TLS scan #6410, fix(relinker): rewrite ALU reads of guest TLS through %fs in macOS output #6419 and this PR merged together, both convert, and 78 of the 79 titles convert (47 onmain, whose 47 outputs are byte-identical).macOS 26.7.1, Apple M2, x86-64 under Rosetta, added 2026-10-16, head 14fb570, with
--macos --to-rosettaand the runtime of a local tree ofmainwith the macOS port work merged: Spider-Man: Edge of Time (PPSA99300), new in the catalog, fails to convert onmain(Guest TLS access without a non-empty PT_TLS) and converts with this branch. Under Rosetta it runs 8 s and then stops on an unexportedllrint(symbol not found in flat namespace '_-431A-YBAks'), which #6345 adds. Dusklight (PPSA99305) runs 4 s and stops in its own renderer (aurora::gpu:No supported adapters).Not tested past the title's own renderer. Dusklight's stop is in its own
aurora::gpurenderer (No supported adapters), not an AnyPS5 error. Like Twilight Princess (PPSA99640), it looks for a GPU adapter from inside the title, and I haven't found the cause, so Dusklight is not tested past that point. Spider-Man's next stop,llrint, is a missing export on every platform (#6345).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)