Files
AnyPS5/docs/dev/debt/libSceFios2.md
T
MarcZX10 dddc4fd030 docs(libSceFios2): cite the call-site source by title ID and record gaps
Cite the PC port that supplied PS4 call-site evidence by owner, commit
and title IDs instead of its repository name, split the file handle
entry under the length the conventions check expects, and record the
operation threading and guest input handling in the technical debt.
2026-10-28 07:27:23 +00:00

24 lines
13 KiB
Markdown

# libSceFios2 technical debt
### Functional
- [libSceFios2 prototypes](../../../core/libs/prx/libSceFios2/include/Api.hpp) (libSceFios2) - the implemented exports take the prototypes of RPCS3's Vita FIOS2 module (`Emu/ARMv7/Modules/sceFios.h` and `sceFios.cpp`, jacquesjk/RPCS-DX12 at `9b8b7c9eea446095f24af19182032013837e6ca5`, 64-bit types substituted), checked against the PS4 headers and call sites of kalaposfos13/fios2 (`src/fios2.h`, `ae6ca1d78e7a822c2528f7660959167b9b3d8b63`), sonny-tel/libSceFios2 (`sceFios2.h`, `5d44f9e7a80ae00557af80fad335e4c74ef35d22`), Inori/GPCS4 (`SceFios2/sce_fios2.cpp`) and SonicMastr/SceLibcPosix (`src/internal/fios2.h`, Vita, `c2cd5e880a8770bdbfb58de761de11f396c1a2e7`).
- [Layouts](../../../core/libs/prx/libSceFios2/include/Api.hpp) (libSceFios2) - The `SceFiosOpAttr`, `SceFiosOpenParams`, `SceFiosStat` and `SceFiosDirEntry` layouts and the `SCE_FIOS_ERROR_*` values (`0x80820000` plus the enumeration order) come from the same sources; vascon-es, a PC port of a PS4 title (CUSA01176 and CUSA00935 version 01.24), at `57c3c202975ea48e574df2d1e4a620b4e18b7701`, confirms the `SceFiosStat` and `SceFiosDirEntry` offsets and the `fileSize`, `statFlags` bit 0 (directory) and `offsetToName` reads from the call sites of a PS4 title. None of it was measured on a PS5. The `SceFiosOpenParams` buffer sits at offset 8 in kalaposfos13 and sonny-tel and at offset 0x10 in vascon-es; only `openFlags` is read
- [Operations](../../../core/libs/prx/libSceFios2/src/Runtime.cpp) (libSceFios2) - there are no I/O or decompressor threads. An operation runs on the calling thread and is complete when the export returns, and its callback fires there with `SCE_FIOS_OPEVENT_COMPLETE`; while `sceFiosSuspend` is in effect new operations queue and run on the thread whose `sceFiosResume` ends the suspension. `deadline`, `priority`, `opflags`, `userTag`, `userPtr` and the scheduler fields are stored and returned but have no effect, and `SCE_FIOS_OPEVENT_START` is never sent. The `*Sync` exports are the asynchronous export followed by `sceFiosOpSyncWait`, so they also fire the completion and `SCE_FIOS_OPEVENT_DELETE` callbacks.
- [Completion values and parameters](../../../core/libs/prx/libSceFios2/src/Runtime.cpp) (libSceFios2) - `sceFiosOpSyncWait` returns the error or the low 32 bits of the result (1 or 0 for the existence queries, as in kalaposfos13/fios2), `sceFiosOpGetActualCount` returns the result (the size for `sceFiosFileGetSize`) also for a failed operation, and `sceFiosOpGetError` returns 1 while an operation is queued; none of these is measured. Handles of operations, files and directories share one number space that starts at 1. Nothing requires `sceFiosInitialize` first, and `SceFiosParams` is stored as `paramsSize` bytes (the 15 bits at bit 1 of the first word) without interpretation, so the storage buffers, `pathMax` (1024 is used), thread and scheduler settings are ignored
- [sceFiosExists, sceFiosFileExists, sceFiosDirectoryExists, sceFiosFileGetSize, sceFiosStat and their Sync forms](../../../core/libs/prx/libSceFios2/src/PathQueries.cpp) (libSceFios2) - paths go to `sceKernelStat`, so archive and alias mapping is the kernel's. A missing path is not an error for the existence queries. `SceFiosStat` carries only the sizes, the nanosecond dates as seconds since 1970 times 10^9 plus nanoseconds (the epoch and unit are not measured), `statFlags` bit 0 for a directory, and the kernel `st_uid`, `st_gid`, `st_dev`, `st_ino` and `st_mode`; other `statFlags` bits are 0. `sceFiosFileExists` and `sceFiosDirectoryExists` take the `pOutExists` argument of RPCS3's prototype, which kalaposfos13/fios2 omits, and `sceFiosFileGetSize` has no output pointer as in kalaposfos13/fios2 and sonny-tel (RPCS3 declares one)
- [sceFiosDelete, sceFiosFileDelete, sceFiosDirectoryCreate, sceFiosDirectoryDelete, sceFiosRename, sceFiosFileRead, sceFiosFileWrite, sceFiosFileTruncate and their Sync forms](../../../core/libs/prx/libSceFios2/src/PathOperations.cpp) (libSceFios2) - behaviour is inferred from the export names; none of it is measured. They run on `sceKernelStat`, `sceKernelOpen`, `sceKernelPread`, `sceKernelPwrite`, `sceKernelFtruncate`, `sceKernelMkdir`, `sceKernelRmdir`, `sceKernelUnlink` and `sceKernelRename`, so guest path mapping and the read-only application directory are the kernel's. `sceFiosFileWrite` opens the file write-only with creation and no truncation, `sceFiosFileTruncate` does not create it, directories are created with mode 0777 and files with 0666, `sceFiosDelete` removes a file or an empty directory, and a negative length returns `SCE_FIOS_ERROR_BAD_SIZE`, a negative offset `SCE_FIOS_ERROR_BAD_OFFSET`.
- [Error mapping](../../../core/libs/prx/libSceFios2/src/PathOperations.cpp) (libSceFios2) - A read stops at the end of the file and returns the bytes read. The mapping of kernel errors to `SCE_FIOS_ERROR_*` is chosen here: `ENOENT` and `ENOTDIR` to `BAD_PATH`, `EPERM`, `EACCES` and `ENOTEMPTY` to `ACCESS`, `EROFS` to `READ_ONLY`, `EEXIST` to `ALREADY_EXISTS`, `EISDIR` to `NOT_A_FILE`, `EINVAL` to `BAD_OFFSET`, `ENFILE` and `EMFILE` to `CANT_ALLOCATE_FH`, `ENAMETOOLONG` to `PATH_TOO_LONG`, `EFAULT` to `BAD_PTR`, and anything else to `UNKNOWN`. The prototypes follow RPCS3 (`sceFios.cpp` `sceFiosFileWrite`, `sceFiosFileTruncate`, `sceFiosRename`, `sceFiosDelete`) and kalaposfos13/fios2 (`sceFiosFileRead`)
- [sceFiosFHOpen, sceFiosFHOpenWithMode, sceFiosFHClose, sceFiosFHStat, sceFiosFHTruncate, sceFiosFHSync, sceFiosFHRead, sceFiosFHWrite, sceFiosFHPread, sceFiosFHPwrite, the vectored forms with their Sync forms, sceFiosFHSeek, sceFiosFHTell, sceFiosFHGetSize, sceFiosFHGetPath and sceFiosFHGetOpenParams](../../../core/libs/prx/libSceFios2/src/FileHandles.cpp) (libSceFios2) - a file handle owns one kernel descriptor, and `sceFiosFHRead`, `sceFiosFHWrite`, `sceFiosFHSeek` and `sceFiosFHTell` use its kernel position.
- [File handle errors and lifetime](../../../core/libs/prx/libSceFios2/src/FileHandles.cpp) (libSceFios2) - `openFlags` map as `SCE_FIOS_O_READ` 1, `SCE_FIOS_O_WRITE` 2, `SCE_FIOS_O_APPEND` 4, `SCE_FIOS_O_CREAT` 8 and `SCE_FIOS_O_TRUNC` 16 (sonny-tel/libSceFios2, SonicMastr/SceLibcPosix); `SCE_FIOS_O_DIRECT` (1 << 12) is ignored, no flags or null parameters open read-only, and the handle returns `SCE_FIOS_ERROR_WRITE_ONLY` or `SCE_FIOS_ERROR_READ_ONLY` for a transfer its flags exclude (the console result is not measured). The creation mode is 0777 unless `sceFiosFHOpenWithMode` is given one (`-1` means the default, as in kalaposfos13/fios2).
- [Open flags and offsets](../../../core/libs/prx/libSceFios2/src/FileHandles.cpp) (libSceFios2) - Opening a directory returns `SCE_FIOS_ERROR_NOT_A_FILE`. An invalid `whence` or a negative resulting position returns `SCE_FIOS_ERROR_BAD_OFFSET`, a vector count outside 1 to 1024 `SCE_FIOS_ERROR_BAD_IOVCNT`. The Readv and Writev exports transfer the vectors in order and stop at the first short one. `sceFiosFHGetPath` and `sceFiosFHGetOpenParams` return pointers that stay valid until the handle is closed; the stored `SceFiosOpenParams` has no buffer. The handle prototypes follow RPCS3's `sceFios.cpp` and kalaposfos13/fios2; `sceFiosFHToFileno` and `sceFiosFilenoToFH` have no source and keep throwing
- [sceFiosDHOpen, sceFiosDHRead, sceFiosDHClose, their Sync forms and sceFiosDHGetPath](../../../core/libs/prx/libSceFios2/src/DirectoryHandles.cpp) (libSceFios2) - the prototypes follow RPCS3 and kalaposfos13/fios2, with the `SceFiosBuffer` passed by value in two registers as in vascon-es. Opening reads the whole listing through `sceKernelGetdirentries` into host memory; the caller's buffer is never written. A title that opens with a null or too small buffer gets `SCE_FIOS_ERROR_BAD_SIZE` and the required size from `sceFiosOpGetActualCount`, the probe that vascon-es observes at the call sites of a PS4 title.
- [Required directory buffer size](../../../core/libs/prx/libSceFios2/src/DirectoryHandles.cpp) (libSceFios2) - The required size, `16` plus the name lengths plus one each, is chosen here and is not what the console reports, so a title that sizes its buffer from another source can get a false `BAD_SIZE`. `.` and `..` are not listed (unverified), entries come in kernel order, the end of the listing returns `SCE_FIOS_ERROR_EOF` and `sceFiosDHRead` fills `fileSize`, `statFlags` bit 0, `nameLength`, `fullPathLength`, `offsetToName` and `fullPath` as vascon-es reads them, with `fullPath` the opened path, a slash and the name
- [sceFiosDateGetCurrent, sceFiosDateFromComponents, sceFiosDateToComponents, sceFiosTimeIntervalFromNanoseconds and sceFiosTimeIntervalToNanoseconds](../../../core/libs/prx/libSceFios2/src/Time.cpp) (libSceFios2) - a `SceFiosDate` is taken as nanoseconds since 1970-01-01 UTC and a `SceFiosTimeInterval` as nanoseconds (identity conversions), as in kalaposfos13/fios2 (`src/fios2.cpp`, `time(nullptr) * 1000000000`) and RPCS3 (`sceFios.cpp`, 64-bit unsigned date); neither is measured, and both may descend from one Vita SDK. kalaposfos13/fios2 converts components through local time, here they are UTC (`sceFiosDateFromComponents` normalizes out-of-range fields like `timegm` and returns 0 before 1970). Only the nine leading `int` fields of `struct tm` are read and written, so `tm_gmtoff` and `tm_zone` are left untouched. `sceFiosTimeGetCurrent` has no source for its clock and keeps throwing
- [Operation threading](../../../core/libs/prx/libSceFios2/src/Runtime.cpp) (libSceFios2) - an operation and its `SCE_FIOS_OPEVENT_COMPLETE` callback run inside the call that issues the operation, whereas on the console the callback runs on a FIOS I/O thread. A title that issues an operation while holding a lock its own callback takes deadlocks on its own thread, and a title that expects the output pointers (`pOutFH`, `pOutExists`, `pOutStatus`) to be written only after `sceFiosOpWait` is not tested. A worker thread was not added: guest callbacks need a guest thread (`scePthreadCreate`, as libSceJobManager uses) with its TLS and stack, the `*Sync` forms must stay synchronous on the caller, and moving completion to another thread changes every output-pointer, callback and teardown ordering in the library and its tests, which could not be validated here against a title or a console
- [Guest inputs](../../../core/libs/prx/libSceFios2/src/Runtime.cpp) (libSceFios2) - `SceFiosOpAttr`, `SceFiosOpenParams`, `SceFiosParams`, the vector arrays and `struct tm` are copied with `GuestCopyIn_nid_no_patch`; a failed copy returns `SCE_FIOS_ERROR_BAD_PTR` (the operation handle value itself for an unreadable `SceFiosOpAttr`), or is ignored by the `void` exports. That the console returns `SCE_FIOS_ERROR_BAD_PTR` for an unreadable pointer is not measured
### Unknown function info
- [sceFiosArchiveGetDecompressorThreadCount, sceFiosArchiveGetMountBufferSize, sceFiosArchiveGetMountBufferSizeSync, sceFiosArchiveMount, sceFiosArchiveMountSync, sceFiosArchiveMountWithOrder, sceFiosArchiveMountWithOrderSync, sceFiosArchiveSetDecompressorThreadCount, sceFiosArchiveUnmount, sceFiosArchiveUnmountSync, sceFiosCacheContainsFileRangeSync, sceFiosCacheContainsFileSync, sceFiosCacheFlushFileRangeSync, sceFiosCacheFlushFileSync, sceFiosCacheFlushSync, sceFiosCachePrefetchFH, sceFiosCachePrefetchFHRange, sceFiosCachePrefetchFHRangeSync, sceFiosCachePrefetchFHSync, sceFiosCachePrefetchFile, sceFiosCachePrefetchFileRange, sceFiosCachePrefetchFileRangeSync, sceFiosCachePrefetchFileSync, sceFiosClearTimeStamps, sceFiosDLLInitialize, sceFiosDLLTerminate, sceFiosDeallocatePassthruFH, sceFiosDebugDumpDH, sceFiosDebugDumpDate, sceFiosDebugDumpError, sceFiosDebugDumpFH, sceFiosDebugDumpOp, sceFiosDirectoryCreateWithMode, sceFiosDirectoryCreateWithModeSync, sceFiosFHToFileno, sceFiosFilenoToFH, sceFiosIOFilterAdd, sceFiosIOFilterCache, sceFiosIOFilterGetInfo, sceFiosIOFilterPsarcDearchiver, sceFiosIOFilterRemove, sceFiosOpReschedule, sceFiosOpRescheduleWithPriority, sceFiosOpSetBuffer, sceFiosOpWaitUntil, sceFiosOverlayAdd, sceFiosOverlayGetInfo, sceFiosOverlayGetList, sceFiosOverlayModify, sceFiosOverlayRemove, sceFiosOverlayResolveSync, sceFiosPathNormalize, sceFiosPathcmp, sceFiosPathncmp, sceFiosPrintTimeStamps, sceFiosPrintf, sceFiosResolve, sceFiosResolveSync, sceFiosSaveTimeStamp, sceFiosTimeGetCurrent, sceFiosTraceTimestamp and sceFiosVprintf](../../../core/libs/prx/libSceFios2/Export.cpp) (libSceFios2) - names and NIDs are present in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceFios2.c), but no credible prototypes were found. The declarations have no parameters solely to resolve known imports; this is not an ABI claim and callers must not call them until signatures are verified