From 44c43c8ebd242d14d799b19230f266182aed79a4 Mon Sep 17 00:00:00 2001 From: Berk Date: Tue, 7 Jul 2026 21:05:54 +0300 Subject: [PATCH] [kernel] Added KernelExceptionCompatExports and fstat, pthread_equal (#30) --- .../Kernel/KernelExceptionCompatExports.cs | 65 +++++++++++++++++++ src/SharpEmu.Libs/Kernel/KernelExports.cs | 7 ++ .../Kernel/KernelPthreadCompatExports.cs | 7 ++ 3 files changed, 79 insertions(+) create mode 100644 src/SharpEmu.Libs/Kernel/KernelExceptionCompatExports.cs diff --git a/src/SharpEmu.Libs/Kernel/KernelExceptionCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelExceptionCompatExports.cs new file mode 100644 index 0000000..417cdd0 --- /dev/null +++ b/src/SharpEmu.Libs/Kernel/KernelExceptionCompatExports.cs @@ -0,0 +1,65 @@ +// Copyright (C) 2026 SharpEmu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +using SharpEmu.HLE; + +namespace SharpEmu.Libs.Kernel; + +public static class KernelExceptionCompatExports +{ + private static readonly HashSet AllowedSignals = new() { 1, 4, 8, 10, 11, 30 }; + private static readonly Dictionary _installedHandlers = new(); + private static readonly object _gate = new(); + + [SysAbiExport( + Nid = "WkwEd3N7w0Y", + ExportName = "sceKernelInstallExceptionHandler", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libKernel")] + public static int InstallExceptionHandler(CpuContext ctx) + { + var signum = unchecked((int)ctx[CpuRegister.Rdi]); + var handler = ctx[CpuRegister.Rsi]; + + if (!AllowedSignals.Contains(signum)) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; + } + + lock (_gate) + { + if (_installedHandlers.ContainsKey(signum)) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_ALREADY_EXISTS; + } + + _installedHandlers[signum] = handler; + } + + ctx[CpuRegister.Rax] = 0; + return (int)OrbisGen2Result.ORBIS_GEN2_OK; + } + + [SysAbiExport( + Nid = "Qhv5ARAoOEc", + ExportName = "sceKernelRemoveExceptionHandler", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libKernel")] + public static int RemoveExceptionHandler(CpuContext ctx) + { + var signum = unchecked((int)ctx[CpuRegister.Rdi]); + + if (!AllowedSignals.Contains(signum)) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; + } + + lock (_gate) + { + _installedHandlers.Remove(signum); + } + + ctx[CpuRegister.Rax] = 0; + return (int)OrbisGen2Result.ORBIS_GEN2_OK; + } +} diff --git a/src/SharpEmu.Libs/Kernel/KernelExports.cs b/src/SharpEmu.Libs/Kernel/KernelExports.cs index 93d920f..2edb2e8 100644 --- a/src/SharpEmu.Libs/Kernel/KernelExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelExports.cs @@ -365,6 +365,13 @@ public static class KernelExports LibraryName = "libKernel")] public static int KernelOpen(CpuContext ctx) => KernelMemoryCompatExports.KernelOpenUnderscore(ctx); + [SysAbiExport( + Nid = "mqQMh1zPPT8", + ExportName = "fstat", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libc")] + public static int Fstat(CpuContext ctx) => KernelMemoryCompatExports.KernelFstat(ctx); + [SysAbiExport( Nid = "hcuQgD53UxM", ExportName = "printf", diff --git a/src/SharpEmu.Libs/Kernel/KernelPthreadCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelPthreadCompatExports.cs index 79c98a9..c2f82b6 100644 --- a/src/SharpEmu.Libs/Kernel/KernelPthreadCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelPthreadCompatExports.cs @@ -95,6 +95,13 @@ public static class KernelPthreadCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_OK; } + [SysAbiExport( + Nid = "7Xl257M4VNI", + ExportName = "pthread_equal", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libc")] + public static int PosixPthreadEqual(CpuContext ctx) => PthreadEqual(ctx); + [SysAbiExport( Nid = "T72hz6ffq08", ExportName = "scePthreadYield",