Repository navigation
fix(savedata): build libSceSaveData and libSceSaveDataDialog from the native sources - #7780
Conversation
… native sources PS4 titles import save data from libSceSaveData and libSceSaveDataDialog, and a converted title loads exactly the modules its DT_NEEDED names. Those two libraries were separate, older implementations that export only 9 and 8 functions, while libSceSaveData.native and libSceSaveDataDialog.native carry sceSaveDataDelete, sceSaveDataDirNameSearch, sceSaveDataSetParam, sceSaveDataSaveIcon, sceSaveDataDialogUpdateStatus and the rest. A PS4 title importing any of those failed at startup with unresolved imports. Both plain libraries are now built from the native sources, the way libSceNgs2 is built from libSceNgs2.native, and the old implementation and its test variant are removed. The earlier implementation's save-data memory and mount alias files are not read; that is recorded in the debt file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Progress report (26ba9b6 → 7394d62)📉 System libraries: 49.99% (-0.07%) 🔗 2 now sharing sources
Changed libraries (implemented exports)
|
|
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.
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.
|
…savedata-ps4-modules # Conflicts: # core/libs/CMakeLists.txt
|
Tested with inFAMOUS Second Son (CUSA00004, my own dump) on Windows 11 Pro, WinLibs GCC 15.2.0 r7, NVIDIA RTX 4070. Setup: this PR's commit On #6977 without this PR, Second Son's save-data imports (
The plain and One more import Second Son needs that neither module has yet is AI-assisted: yes (Claude Code) |
|
@DealPotato thanks for testing with Second Son. Yes, please send |
…savedata-ps4-modules Keep SaveDataCore.hpp deleted: main's RemoveTree change to it (a968336) also applies to the .native Export.cpp this branch builds from, which merged cleanly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@savvaniss done: #8285 adds AI-assisted: yes (Claude Code) |
…savedata-ps4-modules # Conflicts: # core/libs/prx/libSceSaveData/Export.cpp # docs/dev/debt/libSceSaveData.md
…ve debt file The declarations now live in libSceSaveData.native/Export.cpp, which both save data libraries are built from, so their entry belongs in that library's debt file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged
All 13 AI-assisted: yes (Claude Code) |
|
@savvaniss Thanks for waiting on this. Decision on the backend: let's go with native, as this PR does. The plain On the storage layout: I'm fine with the one-time change and no migration, since core couldn't do an ordinary mount and PS4 titles couldn't get far through it. The one case I'd want covered: if you know of PS5 titles that store real save-data memory through the plain module today (65a6531 suggests some import it), a small one-time read of the old Next steps when you have time: merge or rebase on current main (the only conflict I see is |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main's canonical-header refactor (f38d29f) edited the old libSceSaveData and libSceSaveDataDialog sources this branch removes, and made EventFlag.cpp, libSceNpCommon's Runtime.cpp and GuestKernelErrors.cpp include the old SaveDataCore.hpp. Those three use nothing from it and build without it, so the include is dropped. SaveDataWriteReplacement.cpp takes main's canonical header and keeps only the native path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@oneandonlydean thanks for the decision. Migration. I found no PS5 title that keeps real save-data memory through the plain module, so I added no migration:
If such a title turns up, a one-time read of Merge.
It's now marked ready for review, and #8285 can go on top. AI-assisted: yes (Claude Code) |
# Conflicts: # core/libs/tests/GuestSaveDataPs4.cpp
jotitadev
left a comment
There was a problem hiding this comment.
Linux run of head 7394d6254, merged with --no-commit onto main e2d457be3 (clean merge, no conflicts; no file left including SaveDataCore.hpp).
Machine: Linux x86_64, i7-8700, Ubuntu 26.04, GCC 15.2, Release, BUILD_TESTING=ON, incremental build of libs plus the save-data, patched_libraries and guest_kernel_error test targets (770 steps, no new warnings in the save-data sources).
Tests
ctest -R "savedata|patched_libraries|^guest_kernel_errors$": 15/15 pass. That includespatched_libraries, which the description says was not rerun on the merge: it loads the rebuilt plainlibSceSaveData.prx/libSceSaveDataDialog.prxand passes.- The 13 save-data tests plus
patched_libraries,--repeat until-fail:20 -j6: 14/14 pass every round.
Exports (patched .prx, nm -D --defined-only, NIDs only)
| Module | main |
this PR |
|---|---|---|
libSceSaveData |
75 | 132 |
libSceSaveData.native |
66 | 132 |
libSceSaveDataDialog |
8 | 10 |
libSceSaveDataDialog.native |
10 | 10 |
- Every NID that
main's plainlibSceSaveDataandlibSceSaveDataDialogexport is still exported (0 missing), so no title that imports the plain names loses a symbol at link time. The 132 are exactly the union ofmain's two save-data export sets (75 + 66, 9 shared). - The plain and
.nativemodules now export identical NID sets on Linux, matching the equal sizes you saw on Windows (here 191,952 and 16,112 bytes per pair).
Not covered here: the memory-layout change (_sd/sce_sdmemory -> _sd_mem) has no migration test, as the description already says.
Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.
What
PS4 titles import save data from
libSceSaveDataandlibSceSaveDataDialog, and a converted title loads exactly the modules its DT_NEEDED names. Those two libraries were separate, older implementations.libSceSaveDataexports 9 functions (sceSaveDataInitialize3,sceSaveDataTransferringMount, the memory-2 calls, …) andlibSceSaveDataDialogexports 8. The maintained implementations arelibSceSaveData.native(30 functions) andlibSceSaveDataDialog.native(10). They havesceSaveDataDelete,sceSaveDataDirNameSearch,sceSaveDataSetParam,sceSaveDataSaveIcon,sceSaveDataDialogUpdateStatusandsceSaveDataDialogGetStatus, which a PS4 title imports from the plain modules. Such a title failed at startup withunresolved ELF importfor each of them. Details for CUSA03312: #6977 comment.libSceSaveDataandlibSceSaveDataDialogare now built from the.nativesources, the waylibSceNgs2is built fromlibSceNgs2.native(SaveDataLibrary.cmake,SaveDataDialogLibrary.cmake). Their exports become a superset of the old ones: every function the old libraries exported is in the native ones.SaveDataCore.hpp,Export.cpp, 1,487 lines) and itssavedata_core_write_replacementtest variant are removed.SaveDataWriteReplacement.cppkeeps only its native path.SaveDataFile.hppstays where it is, since the native library andsavedata_replace_file_failureinclude it.libSceSaveData: the old implementation kept save-data memory in_sd/sce_sdmemory/<user>/memory.datand mount aliases in_sd/_aliases. The native one uses_sd_mem/u<user>/slot<n>.binand plain_sd/<dir>. Memory saved through the old library is not read after this change. oneandonlydean chose the native layout without a migration (comment), unless a PS5 title is known to keep real save-data memory through the plain module. I found none. No issue, pull request or discussion names a title that callssceSaveDataSetupSaveDataMemory2,sceSaveDataSetSaveDataMemory2orsceSaveDataSyncSaveDataMemory, and that includes the pull requests behind each save-memory fix. 65a6531 only declares pending exports that throw. The gap is recorded indocs/dev/debt/libSceSaveData.md..native.Tested
Windows 11 Pro 26300, WinLibs GCC 15.2.0 r7, Release.
Merges of
main, 24 and 25 Oct:6cd36e6517, merge commit797e2b9733. The only conflict wascore/libs/CMakeLists.txt:mainadded twolibSceNpCppWebApitests next to thesavedata_core_write_replacementlines this branch removes. The merge keeps both tests, and that test stays removed.cceb6c3c41, merge commit7394d62549.main's canonical-header refactor (f38d29f) edited the old sources this branch removes, and they stay removed. Its newinclude/Api.hppheaders forlibSceSaveDataandlibSceSaveDataDialogstay. They declare those modules' exports, which the native sources implement.libkernel'sEventFlag.cpp,libSceNpCommon'sRuntime.cppandGuestKernelErrors.cppinclude the oldSaveDataCore.hpp. They use nothing from it and build without it, so the include is dropped.SaveDataWriteReplacement.cpptakesmain's header and keeps only the native path.All 13 save-data tests and
guest_kernel_errorpass 3 of 3 on the second merge.libkernelandlibSceNpCommonbuild. The save-data tests are:guest_savedata_cancel,_convert,_delete,_dialog,_mount_status,_ps4and_search;savedata_memory_growth,_growth_read_failure,_journaland_metadata;savedata_native_write_replacementandsavedata_replace_file_failure.The built
libSceSaveData.prxandlibSceSaveDataDialog.prxare again the same size as their.nativecounterparts: 271,546 and 81,593 bytes.patched_librarieswas not rerun on the merge, since it loads every built.prx.Earlier runs, on
main7f596df48with the branch rebased onto6b8228b2b:patched_libraries(which loads every built.prx), 3 runs each: 15 of 15 pass onmain, and 14 of 14 with this branch. The difference is the removedsavedata_core_write_replacement. With this branch, the-R "savedata|SaveData|patched_libraries"set includesguest_savedata_cancel,_convert,_delete,_dialog,_mount_status,_search, the foursavedata_memory_*tests,savedata_native_write_replacement,savedata_replace_file_failureandpatched_libraries.libSceSaveData.prxandlibSceSaveDataDialog.prxwere the same size as their.nativecounterparts (266,554 and 81,593 bytes), and their NID exports include Delete, DirNameSearch, SetParam, SaveIcon and DialogUpdateStatus.93eeee014, whose.nativelibrary also has the PS4sceSaveDataInitialize,sceSaveDataMountandsceSaveDataUmount. With onlylibSceSaveData.prxandlibSceSaveDataDialog.prxrebuilt, startup goes from 28 unresolved imports to 20. Exactly the 8 save-data imports resolve and no new import appears. The libraries this branch builds onmainexport 5 of those 8; the other 3 are the PS4 wrappers that feat: run PS4 games on the AGC driver — Limbo (CUSA01664) in game (integration branch) #6977 adds to.native.python3 tools/check_conventions.py --base origin/mainon the merge: no errors. Onedebt-lengthwarning remains, for the 6,140-character pending-declarations entry from 65a6531, which this branch moves tolibSceSaveData.native.mdunchanged.Risk and Monopoly Plus (CUSA03312), 20 Oct: this change resolves their save-data imports. With it in the stack of Hasbro Family Fun Pack (CUSA03312) #7198 (on an RX 9070 XT), Risk plays a local match against the AI and Monopoly Plus reaches its loading screen.
Checklist
Based on current
main; no other open PR implements the same functionsOne 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 fileNo notes, investigation
.mdfiles 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.
tools/pr_overlap.py --branch(24 Oct) lists the following:sceSaveDataMount2) declares the same pending exports and changes the same save-data files. oneandonlydean plans it on top of this pull request.libSceSaveData.native/Export.cpp.core/libs/CMakeLists.txt.Those could not be compared, because they conflict with
main.Fixes: none
Unblocks: CUSA03312 Hasbro Family Fun Pack (CUSA03312) #7198
GPUs tested: n/a
AI-assisted: yes (Claude Code)
🤖 Generated with Claude Code