16 KiB
libSceFios2 technical debt
Functional
-
libSceFios2 prototypes (libSceFios2) - the implemented exports take the prototypes of RPCS3's Vita FIOS2 module (
Emu/ARMv7/Modules/sceFios.handsceFios.cpp, jacquesjk/RPCS-DX12 at9b8b7c9eea446095f24af19182032013837e6ca5, 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 (libSceFios2) - The
SceFiosOpAttr,SceFiosOpenParams,SceFiosStatandSceFiosDirEntrylayouts and theSCE_FIOS_ERROR_*values (0x80820000plus the enumeration order) come from the same sources; vascon-es, a PC port of a PS4 title (CUSA01176 and CUSA00935 version 01.24), at57c3c202975ea48e574df2d1e4a620b4e18b7701, confirms theSceFiosStatandSceFiosDirEntryoffsets and thefileSize,statFlagsbit 0 (directory) andoffsetToNamereads from the call sites of a PS4 title. None of it was measured on a PS5. TheSceFiosOpenParamsbuffer sits at offset 8 in kalaposfos13 and sonny-tel and at offset 0x10 in vascon-es; onlyopenFlagsis read -
Operations (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; whilesceFiosSuspendis in effect new operations queue and run on the thread whosesceFiosResumeends the suspension.deadline,priority,opflags,userTag,userPtrand the scheduler fields are stored and returned but have no effect, andSCE_FIOS_OPEVENT_STARTis never sent. The*Syncexports are the asynchronous export followed bysceFiosOpSyncWait, so they also fire the completion andSCE_FIOS_OPEVENT_DELETEcallbacks. -
Completion values and parameters (libSceFios2) -
sceFiosOpSyncWaitreturns the error or the low 32 bits of the result (1 or 0 for the existence queries, as in kalaposfos13/fios2),sceFiosOpGetActualCountreturns the result (the size forsceFiosFileGetSize) also for a failed operation, andsceFiosOpGetErrorreturns 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 requiressceFiosInitializefirst, andSceFiosParamsis stored asparamsSizebytes (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 (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.SceFiosStatcarries only the sizes, the nanosecond dates as seconds since 1970 times 10^9 plus nanoseconds (the epoch and unit are not measured),statFlagsbit 0 for a directory, and the kernelst_uid,st_gid,st_dev,st_inoandst_mode; otherstatFlagsbits are 0.sceFiosFileExistsandsceFiosDirectoryExiststake thepOutExistsargument of RPCS3's prototype, which kalaposfos13/fios2 omits, andsceFiosFileGetSizehas 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 (libSceFios2) - behaviour is inferred from the export names; none of it is measured. They run on
sceKernelStat,sceKernelOpen,sceKernelPread,sceKernelPwrite,sceKernelFtruncate,sceKernelMkdir,sceKernelRmdir,sceKernelUnlinkandsceKernelRename, so guest path mapping and the read-only application directory are the kernel's.sceFiosFileWriteopens the file write-only with creation and no truncation,sceFiosFileTruncatedoes not create it, directories are created with mode 0777 and files with 0666,sceFiosDeleteremoves a file or an empty directory, and a negative length returnsSCE_FIOS_ERROR_BAD_SIZE, a negative offsetSCE_FIOS_ERROR_BAD_OFFSET. -
Error mapping (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:ENOENTandENOTDIRtoBAD_PATH,EPERM,EACCESandENOTEMPTYtoACCESS,EROFStoREAD_ONLY,EEXISTtoALREADY_EXISTS,EISDIRtoNOT_A_FILE,EINVALtoBAD_OFFSET,ENFILEandEMFILEtoCANT_ALLOCATE_FH,ENAMETOOLONGtoPATH_TOO_LONG,EFAULTtoBAD_PTR, and anything else toUNKNOWN. The prototypes follow RPCS3 (sceFios.cppsceFiosFileWrite,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 (libSceFios2) - a file handle owns one kernel descriptor, and
sceFiosFHRead,sceFiosFHWrite,sceFiosFHSeekandsceFiosFHTelluse its kernel position. -
File handle errors and lifetime (libSceFios2) -
openFlagsmap asSCE_FIOS_O_READ1,SCE_FIOS_O_WRITE2,SCE_FIOS_O_APPEND4,SCE_FIOS_O_CREAT8 andSCE_FIOS_O_TRUNC16 (sonny-tel/libSceFios2, SonicMastr/SceLibcPosix);SCE_FIOS_O_DIRECT(1 << 12) is ignored, no flags or null parameters open read-only, and the handle returnsSCE_FIOS_ERROR_WRITE_ONLYorSCE_FIOS_ERROR_READ_ONLYfor a transfer its flags exclude (the console result is not measured). The creation mode is 0777 unlesssceFiosFHOpenWithModeis given one (-1means the default, as in kalaposfos13/fios2). -
Open flags and offsets (libSceFios2) - Opening a directory returns
SCE_FIOS_ERROR_NOT_A_FILE. An invalidwhenceor a negative resulting position returnsSCE_FIOS_ERROR_BAD_OFFSET, a vector count outside 1 to 1024SCE_FIOS_ERROR_BAD_IOVCNT. The Readv and Writev exports transfer the vectors in order and stop at the first short one.sceFiosFHGetPathandsceFiosFHGetOpenParamsreturn pointers that stay valid until the handle is closed; the storedSceFiosOpenParamshas no buffer. The handle prototypes follow RPCS3'ssceFios.cppand kalaposfos13/fios2;sceFiosFHToFilenoandsceFiosFilenoToFHhave no source and keep throwing -
sceFiosDHOpen, sceFiosDHRead, sceFiosDHClose, their Sync forms and sceFiosDHGetPath (libSceFios2) - the prototypes follow RPCS3 and kalaposfos13/fios2, with the
SceFiosBufferpassed by value in two registers as in vascon-es. Opening reads the whole listing throughsceKernelGetdirentriesinto host memory; the caller's buffer is never written. A title that opens with a null or too small buffer getsSCE_FIOS_ERROR_BAD_SIZEand the required size fromsceFiosOpGetActualCount, the probe that vascon-es observes at the call sites of a PS4 title. -
Required directory buffer size (libSceFios2) - The required size,
16plus 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 falseBAD_SIZE..and..are not listed (unverified), entries come in kernel order, the end of the listing returnsSCE_FIOS_ERROR_EOFandsceFiosDHReadfillsfileSize,statFlagsbit 0,nameLength,fullPathLength,offsetToNameandfullPathas vascon-es reads them, withfullPaththe opened path, a slash and the name -
sceFiosDateGetCurrent, sceFiosDateFromComponents, sceFiosDateToComponents, sceFiosTimeIntervalFromNanoseconds and sceFiosTimeIntervalToNanoseconds (libSceFios2) - a
SceFiosDateis taken as nanoseconds since 1970-01-01 UTC and aSceFiosTimeIntervalas 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 (sceFiosDateFromComponentsnormalizes out-of-range fields liketimegmand returns 0 before 1970). Only the nine leadingintfields ofstruct tmare read and written, sotm_gmtoffandtm_zoneare left untouched.sceFiosTimeGetCurrenthas no source for its clock and keeps throwing -
Operation threading (libSceFios2) - an operation and its
SCE_FIOS_OPEVENT_COMPLETEcallback 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 aftersceFiosOpWaitis not tested. A worker thread was not added: guest callbacks need a guest thread (scePthreadCreate, as libSceJobManager uses) with its TLS and stack, the*Syncforms 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 (libSceFios2) -
SceFiosOpAttr,SceFiosOpenParams,SceFiosParams, the vector arrays andstruct tmare copied withGuestCopyIn_nid_no_patch; a failed copy returnsSCE_FIOS_ERROR_BAD_PTR(the operation handle value itself for an unreadableSceFiosOpAttr), or is ignored by thevoidexports. That the console returnsSCE_FIOS_ERROR_BAD_PTRfor an unreadable pointer is not measured -
sceFiosInitialize, sceFiosUpdateParameters and sceFiosIsInitialized (libSceFios2) - init accepts null/arbitrary sizes and stores raw parameters; updates replace the whole block. PS4 libSceFios2.sprx (init banner SDK 0x10710001), disassembly only: Initialize takes const SceFiosParams* and returns int32_t. Null returns BAD_PTR; size other than 0xb0, nonzero reserved fields or extraFlags beyond quiet return BAD_SIZE; schedulerAlgorithm >= 4 returns BAD_FLAGS. Repeated init returns 0 after UpdateParameters, which ignores calls before init or with another size, otherwise copying only maxChunk, pVprintf, pMemcpy, priorities and affinities. IsInitialized returns the init state and copies 0xb0 bytes to a non-null output only after successful init. PS5 and console behaviour remain unverified
-
SceFiosParams (libSceFios2) - forward-declared without a layout; the implementation does not apply the defaults below. The same module uses every offset of sonny-tel's 0xb0-byte layout and applies these defaults:
pathMax0 or above 1024 becomes 1024;ioThreadCount0 becomes 1 and above 2 becomes 2;threadsPerScheduler0 becomes 1 and above 3 becomes 3;maxChunk0 becomes 0x80000;maxDecompressorThreadCount0 becomes 2 and above 3 becomes 3; a nullpVprintforpMemcpyselects the library's own; a priority of -1 becomes 260, 700 and 260; stack sizes below 0x14000, 0x4000 and 0x4000 are raised to them. The op, FH and DH pools take elements ofpathMaxplus 0x100, 0x70 and 0x68 bytes, rounded up to 8 -
Kernel errors (libSceFios2) - FromKernelError differs from PS4: EFAULT becomes BAD_PTR, EINVAL BAD_OFFSET, ENOTDIR BAD_PATH, ENFILE/EMFILE (23/24) CANT_ALLOCATE_FH, ENAMETOOLONG (63) PATH_TOO_LONG, and unlisted errors UNKNOWN. The same module has no pre-init guard; file calls reach the kernel. Its shared mapper returns ACCESS for EPERM/EACCES/ENOTEMPTY; BAD_PATH for ENOENT/EINVAL/EOPNOTSUPP/ENAMETOOLONG/89; BAD_FH for EBADF; BUSY for EBUSY; ALREADY_EXISTS for EEXIST; MEDIA_GONE for ENODEV/ENOSYS; NOT_A_DIRECTORY for ENOTDIR; NOT_A_FILE for EISDIR; READ_ONLY for EROFS; EOF for ERANGE; TIMEOUT for ETIMEDOUT. Other kernel codes, including EFAULT (0x8002000e), ENFILE and EMFILE, return unchanged. This is PS4 disassembly evidence; PS5 parity is unverified
-
Error codes (libSceFios2) - Types.hpp declares the subset used by the implementation; the source for the full name table is the PS4 module below. The same module's name table gives these
SCE_FIOS_ERROR_names to 0x80820000 plus: 0x00 UNIMPLEMENTED, 0x01 to 0x04 CANT_ALLOCATE_OP, _FH, _DH and _CHUNK, 0x05 BAD_PATH, 0x06 BAD_PTR, 0x07 BAD_OFFSET, 0x08 BAD_SIZE, 0x09 BAD_IOVCNT, 0x0a BAD_OP, 0x0b BAD_FH, 0x0c BAD_DH, 0x0d BAD_ALIGNMENT, 0x0e NOT_A_FILE, 0x0f NOT_A_DIRECTORY, 0x10 EOF, 0x11 TIMEOUT, 0x12 CANCELLED, 0x13 ACCESS, 0x14 DECOMPRESSION, 0x15 READ_ONLY, 0x16 WRITE_ONLY, 0x17 MEDIA_GONE, 0x18 PATH_TOO_LONG, 0x19 TOO_MANY_OVERLAYS, 0x1a BAD_OVERLAY, 0x1b BAD_ORDER, 0x1c BAD_INDEX, 0x1d EVENT_NOT_HANDLED, 0x1e BUSY, 0x1f BAD_ARCHIVE, 0x21 BAD_FLAGS, 0x22 UNKNOWN, 0x23 ALREADY_EXISTS and 0x24 IN_CALLBACK. 0x20 has no name, 0 isSCE_FIOS_OKand 1 isSCE_FIOS_IN_PROGRESS
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 (libSceFios2) - names and NIDs are present in the PS5 3.20 export inventory, 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