Skip to content

feat(libSceRudp): implement sceRudpGetMaxSegmentSize - #4255

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
overlordxrz-source:feat/rudp-get-max-segment-size
Oct 12, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
overlordxrz-source:feat/rudp-get-max-segment-size

Conversation

@overlordxrz-source

Copy link
Copy Markdown
Contributor

What

Implements sceRudpGetMaxSegmentSize (vfrL8gPlm2Y) in libSceRudp with the values measured on a PS5, replacing the NotImplemented_nid_no_patch throw from #3823.

Demon Slayer -Kimetsu no Yaiba- The Hinokami Chronicles (PPSA03490) stops on it. @xXPBSXx reported on #4238 that a run on main d0ca839 ends with what(): sceRudpGetMaxSegmentSize not implemented, thrown from libSceRudp.prx, and on #3073 that with the PlayGo chunk check restored the title mounts its pak directories and then aborts there.

The review of #3823 (adriadam10) asked for either a throw or "a real value with a cited source", with the signature listed as inferred in TechnicalDebt. The source is @hugodearaujo's measurement on a PS5 (firmware 13.60), the same series 4c4e789a3 already uses for sceRudpInit and sceRudpGetStatus:

Call Before sceRudpInit After
sceRudpGetMaxSegmentSize(&v) 0x80770001, v untouched 0, v = 1410 (0x582)
sceRudpGetMaxSegmentSize(NULL) 0x80770001 0x80770004

The call follows that table: under g_mutex, it returns RUDP_ERROR_NOT_INITIALIZED when the library is not initialised (checked before the pointer, as the console does), RUDP_ERROR_INVALID_ARGUMENT for a null pointer, and otherwise writes 1410 and returns 0. After sceRudpTerminate it returns RUDP_ERROR_NOT_INITIALIZED again.

The parameter is uint16_t*, which is inferred. The measurement does not say how many bytes the console writes. The title passes a pointer to a 16-bit value it set to 0, treats a nonzero result as failure and reads the 16-bit value on success (call-site trace in #3073). The PS3 counterpart takes the segment size as u16 (RPCS3 cellRudpSetMaxSegmentSize(u16 mss)). So only 16 bits are written, which cannot overrun the title's variable. No header or emulator gives a parameter list: OpenOrbis Rudp.h declares void sceRudpGetMaxSegmentSize(), and shadPS4, Vita3K and RPCS3 (cellRudpGetMaxSegmentSize) stub it without parameters. TechnicalDebt records what was measured and what is inferred.

Tested

  • guest_rudp_pump now checks sceRudpGetMaxSegmentSize instead of expecting a throw:
    • Before sceRudpInit, it returns 0x80770001 for a valid and for a null pointer, and leaves the value at 0x5a5a.
    • After sceRudpInit, a null pointer returns 0x80770004. A valid pointer gets 1410 with result 0, and a write into the middle element of a uint16_t[3] leaves both neighbours untouched.
    • After sceRudpTerminate, it returns 0x80770001 again and does not write.
    • sceRudpNetReceived still throws.
  • Native Linux run (aarch64, zig 0.17 with glibc, GuestRudpPump.cpp and Export.cpp linked with a NotImplemented_nid_no_patch that throws, Debug and -O1): passes. Three mutants each abort: a value of 1400 fails at the 1410 check, a 32-bit write fails at the neighbour check (and is caught as a misaligned store under UBSan), and checking the pointer before initialisation fails at the null-before-init check.
  • Cross-compiled with zig 0.17 for x86_64-linux-gnu and x86_64-windows-gnu (Export.cpp, GuestRudpPump.cpp): no errors.
  • python3 tools/check_conventions.py with this description: all checks pass.
  • I did not run PPSA03490 myself, and the Windows test was compiled, not executed. Whether the title gets past this call to the packed pixel ancillary stop (Recompiler: packed pixel ancillary word read whole after its VGPR is reused ("unsupported live use (used by BitFieldUExtract 16 11, SelectU32 ...)") #2548) or to the Unreal LowLevelFatalError in the first post of Demon Slayer (PPSA03490) on Windows: Unreal LowLevelFatalError into the title's libc fatal path (libc.prx.guest.prx+0x141b0) #4238 is not shown here.

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
  • New third-party code is a submodule built from source (none added)
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

@github-actions

Copy link
Copy Markdown

Progress report (2263cef → 4b378a2)

📈 System libraries: 86.53% (+0.03%, +1 implemented functions)

✅ 1 implemented
Library Name
libSceRudp sceRudpGetMaxSegmentSize

@overlordxrz-source

Copy link
Copy Markdown
Contributor Author

@xXPBSXx since you have Demon Slayer (PPSA03490) set up on Windows: could you run it with this branch on top of current main and post where it stops next? The value (1410) and the error order come from hugodearaujo's PS5 measurement on #3073. The uint16_t out-parameter is inferred from your gdb trace there, so a run on the real title is the confirmation this PR still needs. Thanks!

AI-assisted: yes

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
#2852 docs/dev/TechnicalDebt.md L77
#2854 docs/dev/TechnicalDebt.md L77
#4074 docs/dev/TechnicalDebt.md L77-78

@oneandonlydean oneandonlydean self-assigned this Oct 12, 2026
@oneandonlydean
oneandonlydean merged commit 5240dd4 into boykopovar:main Oct 12, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants