Skip to content

feat(libc): implement rand_r - #3191

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
reyani-dev:feat/libc-rand-r
Oct 11, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
reyani-dev:feat/libc-rand-r

Conversation

@reyani-dev

Copy link
Copy Markdown
Contributor

Resubmission of #2216, which was closed because no title was shown stopping on rand_r. With tzset (#3124) merged, PS5MC (PPSA99420) now stops at rand_r on main 06da117, per @babyhuey's catalog run with sce_module/libc.prx unwrapped (comment):

app.elf: symbol lookup error: app.elf: undefined symbol: dW3xsu3EgFI

dW3xsu3EgFI is rand_r. With this change the title moves on to rewind (3QIPIh-GDjw, #1871), per the same run. rand_r is still absent on current main, and no open PR implements it. The branch is rebased onto current main. Windows 11 (WinLibs GCC 15.2.0), Release: guest_math passes 3/3, and check_conventions.py and pr_overlap.py --branch pass.


What

Exports rand_r. In FreeBSD, rand and rand_r share one generator step (do_rand in lib/libc/stdlib/rand.c): rand advances the global state, and rand_r advances the caller's unsigned int. This moves the step that rand_nid_postfix already implements into an internal helper (NextRand_nid_no_patch, not exported) used by both, so rand_r matches this libc's rand exactly. rand's behaviour is unchanged. A null state pointer throws std::invalid_argument.

Title: PPSA99420 PS5MC imports it from libSceLibcInternal (resolved through libc.prx), per the #1578 audit. I haven't run the title.

Tested

Windows 11, WinLibs GCC 15.2.0 r7, Release, -DBUILD_TESTING=ON:

  • New checks in guest_math_tests, next to tanf:
    • known answers from the Park-Miller step: state 1 → 33613 and state 0 → 16806, each written back;
    • for seeds 0, 1, 12345, 0x7ffffffe and 0xffffffff, eight rand_r(&seed) calls equal srand(seed) followed by eight rand() calls;
    • null state throws.
  • Mutation check: not writing the state back, or advancing the global state instead, each make guest_math fail.
  • cmake --build build --target libs: the patched libc.prx exports dW3xsu3EgFI (rand_r) and still cpCOXWMgha0 (rand), and the helper isn't exported.
  • tools/check_conventions.py passes, and tools/pr_overlap.py --branch reports no overlap. It also merges cleanly with feat(libc): implement lrand48 and srand48 #2038 (lrand48/srand48, added just below srand), checked with git merge-tree.

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 in TechnicalDebt
  • 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
  • AI-assisted: yes

🤖 Generated with Claude Code

Share rand's generator step with rand_r, which advances the caller's
state instead of the global one, as FreeBSD's rand and rand_r share
do_rand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@reyani-dev reyani-dev mentioned this pull request Oct 11, 2026
9 tasks done
@github-actions

Copy link
Copy Markdown

Progress report (06da117 → 86db61c)

➖ System libraries: 85.96% (+0.0%, +1 implemented functions)

✅ 1 implemented
Library Name
libc rand_r_nid_postfix

@reyani-dev

Copy link
Copy Markdown
Contributor Author

Fork CI for this head merged onto current main (run 38099847203):

  • Windows: 759/759 passed.
  • Linux: 752/755 passed. The 3 failures are agc_unit_shadow, agc_driver_flat_apertures (timeout) and agc_driver_image_packed16_load, which fail identically in main's own push build (run 38098335801). This PR only touches libc, so they're unrelated.
  • Relinker jobs: green.

@github-actions github-actions Bot added the libc label Oct 11, 2026
@babyhuey

Copy link
Copy Markdown
Contributor

Checked with #3190, #3191 and #3192 stacked on main d31b57a (all merge cleanly), catalog builds with sce_module/libc.prx unwrapped. Linux (Ubuntu 24.04, GCC 13) and Windows 11 (WinLibs GCC 15.2), Release: guest_math and guest_strings pass 5/5 (--repeat until-fail:5) on both, with no warnings in Math.cpp or StringExtensions.cpp.

PS5MC (PPSA99420) gets past rand_r on both and stops at setstate:

  • Linux: app.elf: symbol lookup error: app.elf: undefined symbol: woQta4WRpk0
  • Windows: FAIL: unresolved ELF import woQta4WRpk0 (setstate) from libSceLibcInternal.prx

@oneandonlydean
oneandonlydean merged commit 043aac6 into boykopovar:main Oct 11, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants