fix(exports): export the calls PPSA07411 imports

PPSA07411 (Resident Evil 4) fails to load without these imports that no library exports. Their signatures are unknown, so they are declared without parameters and throw until they are implemented. Adds one test and a TechnicalDebt entry.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
xXPBSXx 2026-10-11 16:03:57 +02:00
parent a11c8f7f70
commit a03afed4c3
7 changed files with 134 additions and 0 deletions

View File

@ -27,4 +27,9 @@ int APS5_VABI sceConvertKeycodeGetCharacterFromKeyboardData(void) {
return 0;
}
int APS5_VABI sceConvertKeycodeGetCharacter(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -830,4 +830,25 @@ int APS5_VABI _ZN3sce4Json5Value21setNullAccessCallBackEPFRKS1_NS0_9ValueTypeEPS
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI _ZN3sce4Json5Value30setElementAccessFailureHandlerEPFviPKNS0_6StringEPKmPKS1_S8_PvES9_(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI _ZN3sce4Json5Value22setSpecialFloatHandlerEPFKS1_NS0_12FunctionTypeEdPS2_PvPbES5_(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI _ZN3sce4Json5Value22setTypeMismatchHandlerEPFRKS1_NS0_9ValueTypeEPS2_S5_PvES6_(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI _ZNK3sce4Json5ValuecvbEv(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -93,4 +93,10 @@ int APS5_VABI sceNpSessionSignalingGetConnectionFromPeerAddress(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceNpSessionSignalingGetGroupFromSessionId(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -12,4 +12,13 @@ if(BUILD_TESTING)
set_tests_properties(guest_ssl PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceSsl>")
endif()
add_test_executable(guest_ppsa07411_exports_tests ${LIBS_INCLUDE_DIR}/tests/GuestPPSA07411Exports.cpp)
target_include_directories(guest_ppsa07411_exports_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_ppsa07411_exports_tests PRIVATE libSceSsl libSceJson2 libSceNpSessionSignaling libSceConvertKeycode libc)
configure_windows_unwind(guest_ppsa07411_exports_tests)
add_test(NAME guest_ppsa07411_exports COMMAND guest_ppsa07411_exports_tests)
if(WIN32)
set_tests_properties(guest_ppsa07411_exports PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceSsl>")
endif()
endif()

View File

@ -159,4 +159,34 @@ int APS5_VABI sceSslGetSubjectName(void) {
return 0;
}
int APS5_VABI sceSslCreateConnection(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceSslDeleteConnection(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceSslEnableVerifyOption(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceSslConnect(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceSslRead(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceSslWrite(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -0,0 +1,62 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstdio>
#include <stdexcept>
#include <string>
extern "C" {
int APS5_VABI sceSslCreateConnection();
int APS5_VABI sceSslDeleteConnection();
int APS5_VABI sceSslEnableVerifyOption();
int APS5_VABI sceSslConnect();
int APS5_VABI sceSslRead();
int APS5_VABI sceSslWrite();
int APS5_VABI sceConvertKeycodeGetCharacter();
int APS5_VABI sceNpSessionSignalingGetGroupFromSessionId();
int APS5_VABI _ZN3sce4Json5Value30setElementAccessFailureHandlerEPFviPKNS0_6StringEPKmPKS1_S8_PvES9_();
int APS5_VABI _ZN3sce4Json5Value22setSpecialFloatHandlerEPFKS1_NS0_12FunctionTypeEdPS2_PvPbES5_();
int APS5_VABI _ZN3sce4Json5Value22setTypeMismatchHandlerEPFRKS1_NS0_9ValueTypeEPS2_S5_PvES6_();
int APS5_VABI _ZNK3sce4Json5ValuecvbEv();
}
namespace {
struct Export {
const char* name;
int (APS5_VABI *function)();
};
const Export exports[] = {
{"sceSslCreateConnection", sceSslCreateConnection},
{"sceSslDeleteConnection", sceSslDeleteConnection},
{"sceSslEnableVerifyOption", sceSslEnableVerifyOption},
{"sceSslConnect", sceSslConnect},
{"sceSslRead", sceSslRead},
{"sceSslWrite", sceSslWrite},
{"sceConvertKeycodeGetCharacter", sceConvertKeycodeGetCharacter},
{"sceNpSessionSignalingGetGroupFromSessionId", sceNpSessionSignalingGetGroupFromSessionId},
{"_ZN3sce4Json5Value30setElementAccessFailureHandlerEPFviPKNS0_6StringEPKmPKS1_S8_PvES9_", _ZN3sce4Json5Value30setElementAccessFailureHandlerEPFviPKNS0_6StringEPKmPKS1_S8_PvES9_},
{"_ZN3sce4Json5Value22setSpecialFloatHandlerEPFKS1_NS0_12FunctionTypeEdPS2_PvPbES5_", _ZN3sce4Json5Value22setSpecialFloatHandlerEPFKS1_NS0_12FunctionTypeEdPS2_PvPbES5_},
{"_ZN3sce4Json5Value22setTypeMismatchHandlerEPFRKS1_NS0_9ValueTypeEPS2_S5_PvES6_", _ZN3sce4Json5Value22setTypeMismatchHandlerEPFRKS1_NS0_9ValueTypeEPS2_S5_PvES6_},
{"_ZNK3sce4Json5ValuecvbEv", _ZNK3sce4Json5ValuecvbEv},
};
bool ReportsNotImplemented(const Export& entry) {
try {
entry.function();
} catch (const std::runtime_error& error) {
if (std::string(error.what()) == std::string(entry.name) + " not implemented") return true;
std::fprintf(stderr, "%s threw: %s\n", entry.name, error.what());
return false;
}
std::fprintf(stderr, "%s returned instead of reporting that it is not implemented\n", entry.name);
return false;
}
}
int main() {
bool correct = true;
for (const auto& entry : exports) correct &= ReportsNotImplemented(entry);
return correct ? 0 : 1;
}

View File

@ -597,3 +597,4 @@ Throughout the project, every function at every stage either **does exactly what
- [_fstatfs](../../core/libs/prx/libkernel/File/src/Stdio.cpp) (libkernel) fills the FreeBSD 11 `struct statfs` of the PS5 payload SDK with the host volume that holds the file: block size, transfer size, total, free and available blocks, maximum name length and the read-only, `nosuid` and `noexec` flags (on Windows only read-only, and `f_files` and `f_ffree` are 0, as NTFS has no fixed number of files). The filesystem type number and name, mount paths, owner, filesystem id and I/O counters are left 0 or empty, since they would describe a host mount, not a console one. Sockets and pipes return `EINVAL`, as FreeBSD's `getvnode` does; a Windows descriptor that is neither a file nor a pipe throws. Stremio Plus (PPSA74126) reads the free space before a download and only logs the other fields
- [_WStoul](../../core/libs/prx/libc/src/Strings.cpp), [_Iswctype](../../core/libs/prx/libc/src/RuneLocale.cpp) and [swscanf_s](../../core/libs/prx/libc/src/ScanningWide.cpp) (libc) - `_WStoul` is `wcstoul` and throws for a base other than 0 or 2 to 36. `_Iswctype` takes the class numbers of Dinkumware's [xwcc.h](https://github.com/superna9999/ti-cgt6x/blob/cgt6x_7_3_4/include/xwcc.h) (1 `alnum` to 11 `xdigit`, 12 `blank`) and throws for any other value, including the FreeBSD masks `wctype` returns; the numbering is not confirmed on the console's `libc.prx`. `swscanf_s` follows C11 7.29.2.2 and K.3.9.1.5, but reads the size argument as `unsigned int` like `sscanf_s` where K.3.9.1.5 specifies `rsize_t`; the console's width is unverified. A runtime-constraint violation (null buffer, format or receiving pointer) only returns `EOF`, and a too small array gets a null first element as in `sscanf_s`. A literal mismatch is a matching failure and a field that is only a prefix, such as `0x` or `1e`, does not convert, as C11 requires; FreeBSD's `vfwscanf` reports an input failure for the first and converts the second. Integers out of range are truncated from `strtoll`/`strtoull`. It throws for `%p`, `%S`, `%C`, unknown length modifiers, scanset ranges, `%n` with suppression or width, and narrow `%s`, `%c` or `%[` input that the C-locale `wcrtomb` cannot convert
- [sceSharePlayGetCurrentConnectionInfoA](../../core/libs/prx/libSceSharePlay/Export.cpp) (libSceSharePlay) - reports no Share Play session, as the library keeps none: status 0 (DORMANT), mode 0, empty online IDs, account IDs 0 and both user IDs -1 (`SCE_USER_SERVICE_USER_ID_INVALID`). A null pointer returns `SCE_SHARE_PLAY_ERROR_INVALID_ARGS` (0x810E0001). The 72-byte `SceSharePlayConnectionInfoA` layout and the error code follow [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/libNet.cpp) and [fpPS4](https://github.com/red-prig/fpPS4/blob/trunk/src/ps4_libsceshareplay.pas), which agree on both; KytyPS5 sets the user IDs to -1 and fpPS4 leaves them 0, and which one the console returns is not verified. KytyPS5 also returns `SCE_SHARE_PLAY_ERROR_NOT_INITIALIZED` before `sceSharePlayInitialize`; this library keeps no initialization state and does not.
- PPSA07411 imports declared without parameters, signatures unknown, added without an implementation because the title fails to load without them: [sceSslCreateConnection, sceSslDeleteConnection, sceSslEnableVerifyOption, sceSslConnect, sceSslRead, sceSslWrite](../../core/libs/prx/libSceSsl/Export.cpp) (libSceSsl), [four sce::Json::Value members (setElementAccessFailureHandler, setSpecialFloatHandler, setTypeMismatchHandler, operator bool)](../../core/libs/prx/libSceJson2/Export.cpp) (libSceJson2), [sceConvertKeycodeGetCharacter](../../core/libs/prx/libSceConvertKeycode/Export.cpp) (libSceConvertKeycode) and [sceNpSessionSignalingGetGroupFromSessionId](../../core/libs/prx/libSceNpSessionSignaling/Export.cpp) (libSceNpSessionSignaling)