Feat/sce module load
The game can expect its modified prx from the `sce_module`/`sce_modules` folder. The relinker now converts PRX files from sce_module to `dll`/`so` format with `.guest.prx` postfix. During linking, libraries from `sce_module` are given priority. If a library from `sce_module` fails to import a symbol or contains a syscall, an exception will be thrown.
This made it possible to remove the GuestLocale formats that were customized for specific guests. Launched apps now use their own PRX files from the `sce_module` folder.
Locale handling functions now use `std::locale`.
Added a lot of posix functions to `libkernel` (they are thin wrappers and do what the existing non-posix versions do)
Copy the patched libcohtml.prx to libcohtml.Prospero.prx (exact DT_NEEDED name) via a post-build copy in the module CMakeLists, wired into the libs umbrella target. OUTPUT_NAME with a dot was rejected: the parent pipeline derives unpatched/patched paths from the directory target name, so renaming output would break it; dotted CMake target names are supported (e.g. libSceSaveData.native) but the parent-owned NID-patch rule is kept untouched. Adds DEPLOY.md deploy note. All 50 raw NIDs re-verified in the renamed file export table.
Minecraft Legends' libcohtml.Prospero.prx imports 23 NIDs from lib
libRenoirCore.PS5_v1 (docs/legends-unresolved-nids.json). Clear names are
unknown, so each export is exposed under its raw NID via APS5_EXPORT
alias (<NID>_nid_no_patch_cut), which nid_patcher strips to the
literal NID instead of hashing.
Stubs follow KytyPS5 UnresolvedImportStub policy (log call + return 0)
via APS5_LOG_OUT rather than throwing NotImplemented.
test: wire up the orphaned exception runtime test
- `core/libs/CMakeLists.txt`: registered `ExceptionRuntime.cpp` as `exception_runtime_tests`/`exception_runtime`, following the existing `Guest*.cpp` test pattern, linked against `libc`.
test(agc): fix and re-enable 3 of 8 bitrotted AGC driver tests
- `agc_driver_graphics_tests`: fixed the link failure by adding the three missing source files and linking `shader_recompiler_agc_driver`. Still fails at runtime against stale assertions accumulated over many commits of not being built (an expected "not implemented" message that texture support since removed, and a sampler test fixture value that no longer fits its 12-bit field). Left `EXCLUDE_FROM_ALL`; fixing the assertions is a separate pass across the whole 1150-line test file, not a build fix.
- `agc_driver_recompiler_tests`: root-caused but not fixed. It needs `COMPUTE_NUM_THREAD_X` set, and its pass condition checks for a "not implemented" stub error that no longer exists now that the real recompiler is in. Restoring its original intent needs a shader deliberately built to fail recompilation, which is a design decision, not something this PR should decide unilaterally. Left `EXCLUDE_FROM_ALL`.
- `agc_driver_tests`, `agc_shader_memory_tests`, `agc_driver_flip_tests` and `agc_driver_pm4_tests` already passed; registered them with `add_test` so none of the four can bitrot silently again.
fix: correct sscanf %x signedness and avoid a substr copy
- `core/libs/prx/libSceSysmodule/Export.cpp`: `devMajor`/`devMinor` now `unsigned int`.
- `core/libs/nid/include/nid/NidPatcherUtils.hpp`: two `substr(0, n)` calls replaced with `resize(n)`.
fix(exceptions): interpose libstdc++ ABI on Linux so the project's own unwinder drives it
- `OwnPersonality()` in `Unwind.cpp` now recognises the bare `__gxx_personality_v0` wrapper on Linux too (previously Windows-only).
- `Exports.cpp` exports the real ABI names (`__cxa_throw`, `__cxa_begin_catch`/`end_catch`, `__cxa_rethrow`, `__cxa_allocate`/`free_exception`, `__cxa_call_terminate`, `__cxa_get_exception_ptr`, `__cxa_current_exception_type`, `__cxa_init_primary_exception`, the `std::terminate`/`uncaught_exception(s)` mangled names, and the core `_Unwind_*` entry points) through the existing `GCC_GLOBAL_ALIAS` assembler-alias macro rather than new C++ definitions (a plain redefinition under these names conflicts with `<cxxabi.h>`'s own declarations). This lets ELF symbol interposition make this project's own implementation win process-wide over `libgcc_s.so.1`/`libstdc++.so.6`.
- `__cxa_init_primary_exception_nid_postfix` is new: GCC 13's inline `std::make_exception_ptr` calls `__cxa_init_primary_exception`, and nothing implemented it before.
- Deliberately did not alias `__dynamic_cast`, `__cxa_pure_virtual` or `__cxa_deleted_virtual`. Nothing in `core/libs/prx` needs them rerouted, and doing so would divert every RTTI cast in libstdc++ and third-party code (SDL2, glslang) through this project's slower walker for no benefit.
Kernel error codes were redeclared per file under three prefixes
(SCE_KERNEL_ERROR_, EQUEUE_ERROR_, KERNEL_SEMA_ERROR_), which let wrong
values go unnoticed. Define them once as 0x80020000 | errno for errno
1..94 and use the SCE_KERNEL_ERROR_ names everywhere. Values are unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
SCE kernel errors are 0x80020000 plus the FreeBSD errno. The equeue and
direct memory constants used an unrelated 0x8001xxxx range with mismatched
errno values (e.g. ETIMEDOUT was 0x80010023), so a guest checking
sceKernelWaitEqueue for SCE_KERNEL_ERROR_ETIMEDOUT saw an unexpected error.
SCE_KERNEL_ERROR_EDEADLK in Mutex.cpp held the EAGAIN value.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
SCE kernel errors are 0x80020000 plus the FreeBSD errno. The equeue and
direct memory constants used an unrelated 0x8001xxxx range with mismatched
errno values (e.g. ETIMEDOUT was 0x80010023), so a guest checking
sceKernelWaitEqueue for SCE_KERNEL_ERROR_ETIMEDOUT saw an unexpected error.
SCE_KERNEL_ERROR_EDEADLK in Mutex.cpp held the EAGAIN value.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- scePthreadSelf returned null on Linux and for threads not created by
scePthreadCreate (including the main thread); such threads now get a
lazily adopted, non-joinable handle
- scePthreadExit on Linux skipped FinishThread, losing the join value
- detached threads on Linux were never freed; use the reference count
already used on Windows
- unlocking a recursive mutex from a non-owner was undefined behaviour;
return SCE_KERNEL_ERROR_EPERM
- scePthreadCondTimedwait did not restore the mutex owner after waking,
so another thread locking during the wait made the waiter's unlock
fail with EPERM and left the mutex locked forever
- SCE_KERNEL_ERROR_ETIMEDOUT in Cond.cpp was 0x80020062 instead of 0x8002003C
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Maintainer noted the opt-in-via-documented-flag SPIR-V validation gap
isn't the silent-stub category this doc tracks; the README correction
stands on its own.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Generated executables always used the console subsystem and opened a
console window on launch. The opt-in flag writes IMAGE_SUBSYSTEM_WINDOWS_GUI.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A zero frequency was stored and later used as a divisor when computing
the output block duration. Return SCE_AUDIO_OUT_ERROR_INVALID_SIZE and
SCE_AUDIO_OUT_ERROR_INVALID_SAMPLE_FREQ instead.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
std::system returns a wait status on POSIX, so returning it from main
truncated a guest exit code of 1 (status 256) to 0. The prompt also
required pressing Enter twice because cin.get followed cin.ignore.
Co-Authored-By: Claude Opus 5.5 <[email protected]>