From da3e88a21d137ee000b77157943ce4b62f133d56 Mon Sep 17 00:00:00 2001 From: Alexandre Figueiredo Date: Sun, 25 Oct 2026 00:10:14 +0100 Subject: [PATCH] feat(libSceNpCommon): forward sceNpCloseEventFlag to sceKernelCloseEventFlag --- .../libs/prx/libSceNpCommon/PendingExports.cpp | 5 ----- core/libs/prx/libSceNpCommon/Runtime.cpp | 4 ++++ core/libs/prx/libSceNpCommon/include/Api.hpp | 2 +- core/libs/tests/GuestNpCommonRuntime.cpp | 18 ++++++++++++++++++ docs/dev/debt/libSceNpCommon.md | 5 ++--- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/core/libs/prx/libSceNpCommon/PendingExports.cpp b/core/libs/prx/libSceNpCommon/PendingExports.cpp index 7c3808ebf3..b6479f111b 100644 --- a/core/libs/prx/libSceNpCommon/PendingExports.cpp +++ b/core/libs/prx/libSceNpCommon/PendingExports.cpp @@ -6,11 +6,6 @@ extern "C" { -int APS5_VABI sceNpCloseEventFlag(void) { - NotImplemented_nid_no_patch(__func__); - return 0; -} - int APS5_VABI sceNpCloseSema(void) { NotImplemented_nid_no_patch(__func__); return 0; diff --git a/core/libs/prx/libSceNpCommon/Runtime.cpp b/core/libs/prx/libSceNpCommon/Runtime.cpp index 8c8edda9b4..510328687f 100644 --- a/core/libs/prx/libSceNpCommon/Runtime.cpp +++ b/core/libs/prx/libSceNpCommon/Runtime.cpp @@ -326,6 +326,10 @@ int APS5_VABI sceNpOpenEventFlag(KernelEventFlag* flag, const char* name) { return NpResult(sceKernelOpenEventFlag(flag, name)); } +int APS5_VABI sceNpCloseEventFlag(KernelEventFlag flag) { + return NpResult(sceKernelCloseEventFlag(flag)); +} + int APS5_VABI sceNpSetEventFlag(KernelEventFlag flag, std::uint64_t pattern) { return NpResult(sceKernelSetEventFlag(flag, pattern)); } diff --git a/core/libs/prx/libSceNpCommon/include/Api.hpp b/core/libs/prx/libSceNpCommon/include/Api.hpp index 6e1bf26bc7..d4c373e182 100644 --- a/core/libs/prx/libSceNpCommon/include/Api.hpp +++ b/core/libs/prx/libSceNpCommon/include/Api.hpp @@ -87,7 +87,6 @@ int APS5_VABI sceNpCondTimedwait(PthreadCond* cond, PthreadMutex* mutex, std::ui int APS5_VABI sceNpJoinThread(Pthread thread, void** retval); int APS5_VABI sceNpGetSystemClockUsec(std::int64_t* usec); void APS5_VABI sceNpGetSdkVersion(char* version); -int APS5_VABI sceNpCloseEventFlag(void); int APS5_VABI sceNpCloseSema(void); int APS5_VABI sceNpGetNavSdkVersion(void); int APS5_VABI sceNpIntGetPlatformType(void); @@ -137,6 +136,7 @@ int APS5_VABI sceNpLwCondWait(PthreadCond* cond, PthreadMutex* mutex); int APS5_VABI sceNpCreateEventFlag(KernelEventFlag* flag, const char* name, std::uint32_t attr, std::uint64_t pattern); int APS5_VABI sceNpDeleteEventFlag(KernelEventFlag flag); int APS5_VABI sceNpOpenEventFlag(KernelEventFlag* flag, const char* name); +int APS5_VABI sceNpCloseEventFlag(KernelEventFlag flag); int APS5_VABI sceNpSetEventFlag(KernelEventFlag flag, std::uint64_t pattern); int APS5_VABI sceNpClearEventFlag(KernelEventFlag flag, std::uint64_t pattern); int APS5_VABI sceNpPollEventFlag(KernelEventFlag flag, std::uint64_t pattern, std::uint32_t mode, std::uint64_t* result); diff --git a/core/libs/tests/GuestNpCommonRuntime.cpp b/core/libs/tests/GuestNpCommonRuntime.cpp index 7b2ad35b4c..1747776629 100644 --- a/core/libs/tests/GuestNpCommonRuntime.cpp +++ b/core/libs/tests/GuestNpCommonRuntime.cpp @@ -30,7 +30,10 @@ constexpr int NpOutOfRange = static_cast(0x8055800E); constexpr int NpInvalidArgument = static_cast(0x80558009); constexpr int NpEventFlagBusy = static_cast(0x8055800C); constexpr int NpSemaBusy = static_cast(0x8055800D); +constexpr int KernelNotPermitted = static_cast(0x80020001); +constexpr int KernelNoSuchObject = static_cast(0x80020003); constexpr std::uint32_t EventFlagWaitAnd = 1; +constexpr std::uint32_t EventFlagShared = 0x100; void Require(bool value, const char* message) { if (value) return; @@ -67,6 +70,20 @@ void TestSemaphoresAndFlags() { Require(sceNpDeleteEventFlag(flag) == 0, "the event flag is deleted"); } +void TestSharedEventFlags() { + KernelEventFlag creator {}; + Require(sceNpCreateEventFlag(&creator, "NpSharedFlag", EventFlagShared, 0) == 0, "a shared event flag is created"); + KernelEventFlag opened {}; + Require(sceNpOpenEventFlag(&opened, "NpSharedFlag") == 0 && opened != creator, "the shared event flag is opened by name"); + std::uint64_t result = 0; + Require(sceNpSetEventFlag(opened, 2) == 0 && sceNpPollEventFlag(creator, 2, EventFlagWaitAnd, &result) == 0 && result == 2, + "a bit set through the opened handle is polled through the creator"); + Require(sceNpCloseEventFlag(creator) == KernelNotPermitted, "the creator handle is not closed"); + Require(sceNpCloseEventFlag(opened) == 0, "the opened handle is closed"); + Require(sceNpCloseEventFlag(opened) == KernelNoSuchObject, "a closed handle is gone"); + Require(sceNpDeleteEventFlag(creator) == 0, "the creator deletes the shared event flag"); +} + void TestThreads() { Require(sceNpThreadGetId(nullptr) == NpInvalidArgument, "a null thread id output is refused"); Pthread thread {}; @@ -400,6 +417,7 @@ void TestHexAndCopies() { int main() { TestAtomics(); TestSemaphoresAndFlags(); + TestSharedEventFlags(); TestThreads(); TestHeaps(); TestBase64(); diff --git a/docs/dev/debt/libSceNpCommon.md b/docs/dev/debt/libSceNpCommon.md index da67369967..be7ac29c21 100644 --- a/docs/dev/debt/libSceNpCommon.md +++ b/docs/dev/debt/libSceNpCommon.md @@ -2,9 +2,8 @@ ### Unknown function info -The 35 declarations below use names mapped from the local `libSceNpCommon.sprx` export table. Each NID was verified against that table and recomputed from its name with `tools/nid_names.py`. The public [PS5 3.20 libSceNpCommon export list](https://github.com/DNNDHH/PS5-3.20_Libs/blob/main/libSceNpCommon.c) contains all 150 symbol names. No prototype or behavior is claimed. Each declaration uses the no-parameter unknown-signature convention solely for import resolution and throws if called. +The 34 declarations below use names mapped from the local `libSceNpCommon.sprx` export table. Each NID was verified against that table and recomputed from its name with `tools/nid_names.py`. The public [PS5 3.20 libSceNpCommon export list](https://github.com/DNNDHH/PS5-3.20_Libs/blob/main/libSceNpCommon.c) contains all 150 symbol names. No prototype or behavior is claimed. Each declaration uses the no-parameter unknown-signature convention solely for import resolution and throws if called. -- [sceNpCloseEventFlag](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) (NID `+nmn+Z0nWDo`) - the signature and behavior are unknown. The no-parameter declaration only resolves the import; it makes no ABI claim. Calls throw through `NotImplemented_nid_no_patch`. - [sceNpCloseSema](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) (NID `8hPzfjZzV88`) - the signature and behavior are unknown. The no-parameter declaration only resolves the import; it makes no ABI claim. Calls throw through `NotImplemented_nid_no_patch`. - [sceNpGetNavSdkVersion](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) (NID `QmDEFikd3VA`) - the signature and behavior are unknown. The no-parameter declaration only resolves the import; it makes no ABI claim. Calls throw through `NotImplemented_nid_no_patch`. - [sceNpIntGetPlatformType](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) (NID `G6qytFoBJ-w`) - the signature and behavior are unknown. The no-parameter declaration only resolves the import; it makes no ABI claim. Calls throw through `NotImplemented_nid_no_patch`. @@ -54,6 +53,6 @@ The 35 declarations below use names mapped from the local `libSceNpCommon.sprx` - [The string-to-integer exports](../../../core/libs/prx/libSceNpCommon/Strings.cpp) clear `errno` before parsing; the firmware reads whatever `errno` held before the call when the result saturates. - [The integer-to-string exports](../../../core/libs/prx/libSceNpCommon/Strings.cpp) return `0x80558008` when the hexadecimal prefix does not fit; the firmware writes the prefix without checking the size. [The base64 decoders](../../../core/libs/prx/libSceNpCommon/Strings.cpp) treat bytes above 0x7F as invalid; the firmware indexes its table with them as signed values. [sceNpUtilJsonGetOneChar](../../../core/libs/prx/libSceNpCommon/Strings.cpp) checks that a `\u` escape and a surrogate pair fit in the input; the firmware reads past it. - [sceNpUtilGetNpDebug, sceNpUtilGetNpTestPatch, sceNpUtilGetTrcNotify, sceNpUtilGetIgnoreNpTitleId, sceNpUtilGetFakeDisplayNameMode, sceNpUtilGetWebTraceSetting, sceNpUtilGetWebApi2FakeRateLimit, sceNpUtilGetWebApi2FakeRateLimitTarget, sceNpUtilGetFakeRateLimit, sceNpUtilGetDbgCommerce, sceNpUtilGetSystemLanguage, sceNpUtilGetEnv, sceNpUtilGetDateSetAuto and sceNpUtilGetShareTitleCheck](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) read system and debug registry keys through libSceRegMgr, whose `sceRegMgrNonSysGetInt` and string reads still throw; they throw until those exist. -- [sceNpOpenSema, sceNpCloseSema and sceNpCloseEventFlag](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) forward to the libkernel open and close calls for named semaphores and event flags, which still throw. +- [sceNpOpenSema and sceNpCloseSema](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) forward to the libkernel open and close calls for named semaphores, which still throw. - [sceNpSetPlatformType, sceNpIntGetPlatformType, sceNpIntSetPlatformType, sceNpUtilCanonicalizeNpIdForPs4, sceNpUtilCanonicalizeNpIdForPsp2, sceNpUtilJidToNpId and sceNpGetNavSdkVersion](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) depend on console platform tags, network domain names or a version string of the console; they throw. - [sceNpJsonParse, sceNpJsonParseInit, sceNpJsonParseBuf, sceNpJsonParseBufInit, sceNpJsonParseEx, sceNpJsonParseExInit and the sceNpServerErrorJson exports](../../../core/libs/prx/libSceNpCommon/PendingExports.cpp) are a streaming, schema-checked JSON parser whose event and error rules are not yet specified; they throw.