diff --git a/core/libs/prx/libSceFiber/Export.cpp b/core/libs/prx/libSceFiber/Export.cpp index 83572e7d1..5935f1bad 100644 --- a/core/libs/prx/libSceFiber/Export.cpp +++ b/core/libs/prx/libSceFiber/Export.cpp @@ -458,6 +458,10 @@ int32_t APS5_VABI sceFiberGetThreadFramePointerAddress(uint64_t* addr_frame_poin return SCE_OK; } +int32_t APS5_VABI _sceFiberGetThreadFramePointerAddress(uint64_t* addr_frame_pointer) { + return sceFiberGetThreadFramePointerAddress(addr_frame_pointer); +} + int32_t APS5_VABI sceFiberStartContextSizeCheck(uint32_t flags) { if (flags != 0) return SCE_FIBER_ERROR_INVALID; bool expected = false; diff --git a/core/libs/tests/Fiber.cpp b/core/libs/tests/Fiber.cpp index da0721409..ccd01ed4a 100644 --- a/core/libs/tests/Fiber.cpp +++ b/core/libs/tests/Fiber.cpp @@ -18,6 +18,7 @@ std::int32_t APS5_VABI sceFiberReturnToThread(std::uint64_t, std::uint64_t*); std::int32_t APS5_VABI sceFiberGetSelf(FiberObject**); std::int32_t APS5_VABI sceFiberGetInfo(FiberObject*, FiberInfo*); std::int32_t APS5_VABI sceFiberGetThreadFramePointerAddress(std::uint64_t*); +std::int32_t APS5_VABI _sceFiberGetThreadFramePointerAddress(std::uint64_t*); std::int32_t APS5_VABI sceFiberStartContextSizeCheck(std::uint32_t); std::int32_t APS5_VABI sceFiberStopContextSizeCheck(void); } @@ -54,6 +55,9 @@ void APS5_VABI FirstEntry(std::uint64_t argOnInitialize, std::uint64_t argOnRun) std::uint64_t framePointer = 0; Require(sceFiberGetThreadFramePointerAddress(nullptr) == FiberErrorNull, "frame pointer null"); Require(sceFiberGetThreadFramePointerAddress(&framePointer) == 0 && framePointer == g_threadFramePointer, "thread frame pointer"); + framePointer = 0; + Require(_sceFiberGetThreadFramePointerAddress(nullptr) == FiberErrorNull, "underscore frame pointer null"); + Require(_sceFiberGetThreadFramePointerAddress(&framePointer) == 0 && framePointer == g_threadFramePointer, "underscore thread frame pointer"); volatile double carried = 1.5; std::uint64_t received = 0; Require(sceFiberSwitch(g_second, 200, &received) == 0, "switch to second fiber"); @@ -124,6 +128,7 @@ int main() { std::uint64_t returned = 0; std::uint64_t framePointer = 0; Require(sceFiberGetThreadFramePointerAddress(&framePointer) == FiberErrorPermission, "frame pointer outside a fiber"); + Require(_sceFiberGetThreadFramePointerAddress(&framePointer) == FiberErrorPermission, "underscore frame pointer outside a fiber"); Require(RunFirst(&returned) == 0 && returned == 250, "run first until second returns"); Require(_mm_getcsr() == threadCsr, "thread MXCSR restored after the fibers"); std::thread([&] { diff --git a/docs/dev/TechnicalDebt.md b/docs/dev/TechnicalDebt.md index 0c72b62a7..7532750dc 100644 --- a/docs/dev/TechnicalDebt.md +++ b/docs/dev/TechnicalDebt.md @@ -343,6 +343,8 @@ Throughout the project, every function at every stage either **does exactly what - [sceAppContentGetAddcontDownloadProgress](../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - imported by PPSA08755, which fails to load without it; added without an implementation because its behavior is unverified. [SharpProspero](https://github.com/SvenGDK/SharpProspero) lists `(uint32_t serviceLabel, entitlementLabel, SceAppContentAddcontDownloadProgress*)`, but no PS5 reference gives the progress layout or the error codes +- [_sceFiberGetThreadFramePointerAddress](../../core/libs/prx/libSceFiber/Export.cpp) (libSceFiber, NID `0dy4JtMUcMQ`) forwards to `sceFiberGetThreadFramePointerAddress`; that the argument list matches is inferred from the export without the underscore, as for the underscore Ult exports, not measured + ### Functional - [getc_unlocked, putc_unlocked](../../core/libs/prx/libc/src/StandardStreams.cpp) (libc) - byte I/O uses the host unlocked operations; guest EOF/error flags and macro counters follow `FileStream`. Linux status queries use `feof_unlocked`/`ferror_unlocked` because [glibc `feof`](https://github.com/bminor/glibc/blob/d2097651cc57834dbfcaa102ddfacae0d86cfb66/libio/feof.c) and [`ferror`](https://github.com/bminor/glibc/blob/d2097651cc57834dbfcaa102ddfacae0d86cfb66/libio/ferror.c) can acquire the stream lock. Windows uses [the CRT no-lock byte operations](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fgetc-nolock-fgetwc-nolock) and `feof`/`ferror`, verified under a held stream lock on UCRT. Console behavior and other host CRTs remain unverified.