Repository navigation
feat(libc): implement the Dinkumware mtx and cnd functions - #1952
overlordxrz-source wants to merge 1 commit into
Conversation
Cyberpunk 2077 (PPSA04029) imports _Mtx_init, _Mtx_destroy, _Mtx_lock, _Mtx_unlock, _Cnd_init, _Cnd_destroy, _Cnd_wait and _Cnd_broadcast, which were throwing libcCyberUnknown stubs. Each name hashes to the stub's NID. _Mtx_trylock and _Cnd_signal complete the set other titles import. The guest's _Mtx_t and _Cnd_t hold a pointer to host state, created on first use when zero. type & 0x100 selects a recursive mutex; other bits give a plain one that, like Sony's error-checking pthread mutex, returns _Thrd_busy (3) on relock or a busy trylock and _Thrd_error (4) when the caller does not own it.
Progress report (f145139 → 9a33c0b)📈 System libraries: 85.03% (+0.27%, +10 implemented, -8 removed functions) ✅ 10 implemented
🗑️ 8 removed
|
MarcZX10
left a comment
There was a problem hiding this comment.
Blocking ABI question: every operation export in Threads.cpp currently accepts LibcMutex** / LibcCondition** and dereferences the argument as a slot. The corresponding Dinkumware handle types are _Mtx_t = _Mtx_internal_imp_t* and _Cnd_t = _Cnd_internal_imp_t*; _Mtx_lock, _Mtx_trylock, _Mtx_unlock, _Mtx_destroy, _Cnd_wait, _Cnd_signal, _Cnd_broadcast, and _Cnd_destroy take those handles by value. Only _Mtx_init and _Cnd_init take pointer-to-handle. The official declarations are in Microsoft STL xthreads.h and the handle definitions in __msvc_threads_core.hpp.
The new test declares all operations as void** and passes &mutex / &condition, so it reproduces the implementation's assumption instead of checking the caller ABI. Please provide disassembly or another source showing that the PS5 wrappers intentionally use pointer-to-slot for these non-init functions. If they use the Dinkumware handle ABI, adjust the export signatures and tests so callers pass the stored handle itself; otherwise a real title passes an object pointer that this code interprets as a pointer slot.
|
Thanks for checking this against the headers. I looked into it, and the PS4/PS5 libc uses the older Dinkumware signatures, where every
fpPS4 doesn't implement So I've kept the |
|
Closing: only import lists show these, and Cyberpunk's PPSA03974 build ships its own |
…d cnd functions Harvested from upstream (closed as need-gated, not on quality). Hand merge: the PR replaces the placeholder exports in libc/Export.cpp with src/Threads.cpp, while the stack had already renamed those placeholders to _Cnd_*/_Mtx_* stubs. Kept our Export.cpp and deleted the eight stubs that Threads.cpp now implements. Library completion 2935/3298 -> 2945/3300. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011krDVCnnMQPaEFEqCDnKmA
What
Cyberpunk 2077 (PPSA04029) imports eight Dinkumware thread functions that
libconly has as throwinglibcCyberUnknown*stubs. Each name hashes to its stub's NID withtools/nid_names.py'scompute_nid, andpython3 tools/nid_names.pyalready lists them as rename-ready:YaHc3GS7y7glibcCyberUnknown12_Mtx_init5Lf51jvohTQlibcCyberUnknown03_Mtx_destroyiS4aWbUonl0libcCyberUnknown14_Mtx_lockgTuXQwP9rrslibcCyberUnknown13_Mtx_unlockSreZybSRWpUlibcCyberUnknown10_Cnd_init7yMFgcS8EPAlibcCyberUnknown05_Cnd_destroyvEaqE-7IZYclibcCyberUnknown16_Cnd_waitVsP3daJgmVAlibcCyberUnknown11_Cnd_broadcastIt also adds
_Mtx_trylock(k6pGNMwJB08, which Minecraft Legends PPSA05510 imports according to #268) and_Cnd_signal(0uuqgRz9qfo, imported by GTA III Definitive, PPSA05510 and Deathloop according to #267, #268 and #272). The eight Cyberpunk NIDs are also in the import lists of #267, #268 and #272.This follows the review on #492, which was closed with an invitation to reopen with only the mtx/cnd functions:
_Mtx_initmakes the mutex recursive only whentype & 0x100is set._Mtx_plain,_Mtx_tryand_Mtx_timedgive a plain mutex._Mtx_lockand_Mtx_trylockreturn 3 (_Thrd_busy) when a plain mutex is relocked by its owner or when trylock finds it busy._Mtx_unlockand_Cnd_waitreturn 4 (_Thrd_error) when the caller does not own the mutex, and so does a call with a null pointer._Mtx_t/_Cnd_t, which holds one pointer to host state. This is the pre-VS2015 Dinkumware<xthreads.h>ABI (_Mtx_lock(_Mtx_t *),_Cnd_wait(_Cnd_t *, _Mtx_t *)) that fpPS4's reverse-engineeredlibSceLibcInternalfollows under the same NIDs. A zeroed one is set up on first use, the way libkernel handles a static mutex._Mtx_destroyand_Cnd_destroyreturnvoidand clear the slot._Cnd_waiton a recursive mutex releases every level and restores the count after waking.The review suggested going through libkernel's
scePthreadMutex*/scePthreadCond*. That isn't possible here becauselibkernellinkslibc(core/libs/prx/libkernel/CMakeLists.txt), solibc/src/Threads.cppkeeps its own host state and returns the codes that the error-checking pthread mutex would produce through Sony's wrapper.Not included, because they are separate topics:
abs(Ye20uNnlglA, in #1097),__powidf2,_WStoul,_Iswctype,vsnprintf_sandvsscanf_s. #1498 also changes these eight stubs, without renaming them. ItslibcCyberUnknown13locks and itslibcCyberUnknown14unlocks, but the NIDs say 13 is_Mtx_unlockand 14 is_Mtx_lock.Log
I don't own Cyberpunk 2077, so I can't paste the line where PPSA04029 stops on
main, and I found no issue or discussion that names one of these NIDs as a stop. The evidence is the PPSA04029 relinker import list in #266, where all eight NIDs appear, and the existing stubs onmainthat were added for this title in #358. If someone with the title can post theNotImplementedline it reaches onmain, I'll add it here.Tested
aarch64 Debian 13 host. The full project can't be built here because it needs x86-64.
core/libs/tests/GuestLibcThreads.cpp(guest_libc_threads), linked natively againstThreads.cpp, passes 30 out of 30 runs, and also passes under ASan and UBSan. It checks plain types 1, 2, 3 and 5 (relock and busy trylock return 3; unlock and trylock from another thread return 4 and 3; a second unlock returns 4), a recursive mutex with nested lock and trylock that blocks another thread until fully released, eight-thread contention, zeroed slots, broadcast waking four waiters, signal handing out three tokens, waiting on an unowned mutex returning 4, a wait on a twice-locked recursive mutex restoring its count, and null arguments.Threads.cpp,Export.cppand the test compile for x86_64-linux-gnu and x86_64-windows-gnu with-Wall -Wextra(Zig 0.17 clang). The only warning is the existing-Wreturn-type-c-linkagefromGeneral.hpp.python3 tools/check_conventions.py --base origin/mainpasses.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)