Skip to content

fix(libc): match shipped CRT ABI and constraint behavior - #8711

Closed
ivica00 wants to merge 1 commit into
boykopovar:mainfrom
ivica00:codex/crt-shipped-contracts
Closed

ivica00 wants to merge 1 commit into
boykopovar:mainfrom
ivica00:codex/crt-shipped-contracts

Conversation

@ivica00

@ivica00 ivica00 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

What

Match the shipped CRT contracts for _Thrd_id, strtok_s, asctime_s and ctime_s, including the AMPR wrappers that share the bounded-string helpers. This corrects ABI and constraint behavior rather than adding title-specific fallbacks.

  • _Thrd_id returns the full scePthreadSelf handle. Register a self callback alongside the existing create/join callbacks to preserve libc/kernel dependency direction; missing registration throws. The shipped export (NID np6xXcXEnXE, ELF VA 0x4c70) calls PLT 0xcab10, whose relocation names scePthreadSelf (aI+OeCz8xrQ), and returns RAX unchanged.
  • strtok_s (NID -vXEQdRADLI, VA 0x71590) has four arguments: source, remaining-size pointer, delimiters, context pointer. Preserve its bounded scan, remaining-count/context updates, delimiter writes and error precedence, including the distinct bad argument, missing token and missing delimiter callbacks.
  • asctime_s (qPe7-h5Jnuc, VA 0x71b30) and ctime_s (2UFh+YKfuzk, VA 0x71be0) reject zero or >=2^61 destination sizes without writing, and clear a valid destination on subsequent argument failure. Match observed field ranges and callback diagnostics, with EINVAL, null callback pointer argument and guest calling convention. Boundary years format as four digits.

Evidence: REA rea-agents@6.7.0 with Ghidra 12.1.4 and JDK 21, using small PE wrappers containing unchanged code slices from the title's unwrapped libc. ELF symbols, relocations and raw instructions establish the ABI; inferred PE calling conventions do not. Unwrapped libc SHA-256: 0e0a628ad9a635ab7b13a3516cf13be092e34cafb84929a7a66740347273da3e. Code-slice SHA-256: thread 55b1bc8f5b303027829a07250e2fd18a97c65591fa4bfc771887084e0317f1fa, date/tokenizer page 18b3cb29afc2971d652e1c7bde6c3bbf09fdb906c4eae73a19e701196da91957.

The earlier local shared-handler-state refactor is excluded because #7081 addresses it. This PR preserves current main's handler storage and does not duplicate #7841's bounds-function additions or #7952's wcscpy_s work. Remaining locale/timezone, cross-SDK and console-verification limits are recorded in libc technical debt. No proprietary binaries or generated investigation files are committed.

Overlap review: #8636 implements _Thrd_detach and explicitly leaves _Thrd_id as a throwing stub; our binary evidence resolves the width question it records. Its callback registration additions occupy adjacent lines, so this PR is a draft with #8636 listed for merge-order coordination, not a duplicate implementation. The intended order is #8636 first, then rebase these self-callback additions; no detach code is copied here. Maintainer/author agreement on that order is still pending.

Manually reviewed every incomparable shared-file diff from the overlap tool: #1835/#5021/#7201 change timed waits or numeric conversion, #6879 changes wcstof, #6044 moves tests, #7081 changes shared handler/locale state, and #7648 changes errno/thread launch plumbing. Remaining shared debt-file edits in #6226, #6469, #6819, #7473, #7715, #8150 and #8520 concern unrelated entries. #7081 will need mechanical reconciliation if it lands later, but its shared-state implementation is excluded here. No other inspected PR implements the tokenizer/date contracts or _Thrd_id fix proposed here.

Tested

Windows 10 (10.0.19045), AMD Ryzen 5 7600, MinGW GCC 15.2.0, Release full-library configuration with dependencies built from source. Built the relevant library and test targets; guest_crt, guest_ampr_threads, guest_libc_threads, guest_strings, guest_time_conversion, guest_strftime and guest_wide_conversion passed (7/7).

The tokenizer also passed 128,253 original-versus-implementation calls across 50,000 deterministic randomized sequences. A local harness mapped only the shipped ELF's isolated tokenizer/helpers, intercepted its constraint callback, and compared return offsets, remaining counts, context offsets, complete buffers and callback count/message/pointer/error against this branch's built libc. No game initialization was invoked. The harness and proprietary input remain outside the repository.

Focused tests exercise both libc and AMPR wrappers, every date-field boundary, invalid destination sizes and write behavior, tokenizer constraints/continuations/high-byte delimiters, and stable distinct full-pointer thread identities on the main thread plus four simultaneous guest threads.

check_conventions.py --base upstream/main passes. The required --base origin/main was attempted but encounters WinError 206 because the fork's old main produces a large unrelated upstream export delta; the actual upstream PR base passes. No checker source was altered.

The game, Linux runtime and retail console were not run. The isolated tokenizer comparison is direct binary execution; thread/date findings are disassembly plus host regression tests. No speed or FPS claim is made.

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: feat(libc): implement _Thrd_detach #8636 (merge order for adjacent registration edits; coordination pending)
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

@github-actions

Copy link
Copy Markdown

Progress report (bcdb033 → 0705e28)

📈 System libraries: 64.51% (+0.01%, +1 implemented functions)

✅ 1 implemented
Library Name
libc _Thrd_id_nid_postfix

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

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 1835 core/libs/prx/libc/src/Threads.cpp
PR 3965 docs/dev/debt/libc.md
PR 3987 docs/dev/debt/libc.md
PR 5021 core/libs/prx/libc/src/Strings.cpp
core/libs/prx/libc/src/Threads.cpp
docs/dev/debt/libc.md
PR 5303 docs/dev/debt/libc.md
PR 6044 core/libs/tests/GuestAmprThreads.cpp
core/libs/tests/GuestCrt.cpp
PR 6086 core/libs/prx/libc/src/Threads.cpp
PR 6226 docs/dev/debt/libc.md
PR 6469 docs/dev/debt/libc.md
PR 6565 docs/dev/debt/libc.md
PR 6713 docs/dev/debt/libc.md
PR 6819 docs/dev/debt/libc.md
PR 6879 core/libs/prx/libc/src/Strings.cpp
docs/dev/debt/libc.md
PR 7081 core/libs/prx/libSceAmpr/Export.cpp
core/libs/prx/libc/include/SonyCrt.hpp
core/libs/tests/GuestCrt.cpp
docs/dev/debt/libc.md
PR 7135 core/libs/prx/libkernel/Pthread/Posix/Thread.cpp
PR 7201 core/libs/prx/libc/src/Strings.cpp
core/libs/prx/libc/src/Threads.cpp
PR 7386 docs/dev/debt/libc.md
PR 7447 docs/dev/debt/libc.md
PR 7525 docs/dev/debt/libc.md
PR 7544 docs/dev/debt/libc.md
PR 7648 core/libs/prx/libSceAmpr/Export.cpp
docs/dev/debt/libc.md
PR 7715 docs/dev/debt/libc.md
PR 7841 docs/dev/debt/libc.md
PR 7853 core/libs/prx/libkernel/Pthread/Posix/Thread.cpp
PR 7952 core/libs/prx/libc/include/SonyCrt.hpp
docs/dev/debt/libc.md
PR 7979 core/libs/prx/libc/src/Strings.cpp
PR 8061 core/libs/prx/libkernel/Pthread/Posix/Thread.cpp
PR 8087 docs/dev/debt/libc.md
PR 8150 docs/dev/debt/libc.md
PR 8279 docs/dev/debt/libc.md
PR 8284 docs/dev/debt/libc.md
PR 8287 docs/dev/debt/libc.md
PR 8306 docs/dev/debt/libc.md
PR 8352 core/libs/prx/libc/src/Threads.cpp
docs/dev/debt/libc.md
PR 8376 docs/dev/debt/libc.md
PR 8384 docs/dev/debt/libc.md
PR 8397 docs/dev/debt/libc.md
PR 8417 docs/dev/debt/libc.md
PR 8479 docs/dev/debt/libc.md
PR 8520 docs/dev/debt/libc.md
PR 8546 docs/dev/debt/libc.md
PR 8550 docs/dev/debt/libc.md
PR 8658 core/libs/prx/libc/src/Strings.cpp
PR 8720 docs/dev/debt/libc.md
PR 8730 docs/dev/debt/libc.md
PR 8849 core/libs/prx/libc/include/General.hpp
core/libs/prx/libc/src/Strings.cpp
PR 8855 core/libs/tests/GuestAmprThreads.cpp
docs/dev/debt/libc.md
PR 8859 core/libs/prx/libc/include/General.hpp
core/libs/prx/libc/src/Threads.cpp
core/libs/prx/libkernel/Pthread/Posix/Thread.cpp
PR 8863 docs/dev/debt/libc.md
PR 8864 docs/dev/debt/libc.md
PR 8865 core/libs/prx/libc/src/Strings.cpp
docs/dev/debt/libc.md
PR 8872 core/libs/prx/libc/include/General.hpp
docs/dev/debt/libc.md
PR 8880 core/libs/prx/libSceAmpr/Export.cpp
docs/dev/debt/libc.md
PR 8885 core/libs/prx/libc/include/General.hpp
core/libs/prx/libc/src/Threads.cpp
core/libs/prx/libkernel/Pthread/Posix/Thread.cpp
PR 8890 core/libs/prx/libkernel/Pthread/Posix/Thread.cpp
PR 8903 docs/dev/debt/libc.md
PR 8937 docs/dev/debt/libc.md
PR 8941 docs/dev/debt/libc.md

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

Labels

docs libc libkernel needs rebase Conflicts with main, rebase needed prx

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant