Improve signal emulation (#4108)

* improve signal emulation

* make the sce function use the new posix ones

* ifdefing away the issues

* fix me being very tired yesterday night

* let macOS handle SIGRT signals with the native sigaction call instead of an early error return

* windows still has no clue what the fuck is going on

* the loathsome clang-formatter

* fix oact

* return the guest handler, not the host one

* Clear any existing signal mask for game threads.

* don't rely on implementation specific things

* Fix Windows support and sceKernelRaiseException bug

* Review suggestions

@kalaposfos13 suggested I push these.

---------

Co-authored-by: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com>
This commit is contained in:
kalaposfos13 2026-03-09 13:20:14 +01:00 committed by GitHub
parent cc6af03adf
commit 0579569f13
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 277 additions and 74 deletions

View File

@ -788,14 +788,11 @@ static bool PatchesIllegalInstructionHandler(void* context) {
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]; ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
const auto status = const auto status =
Common::Decoder::Instance()->decodeInstruction(instruction, operands, code_address); Common::Decoder::Instance()->decodeInstruction(instruction, operands, code_address);
if (ZYAN_SUCCESS(status) && instruction.mnemonic == ZydisMnemonic::ZYDIS_MNEMONIC_UD2) LOG_ERROR(Core, "Failed to patch address {:x} -- mnemonic: {}",
[[unlikely]] { reinterpret_cast<u64>(code_address),
UNREACHABLE_MSG("ud2 at code address {:#x}", reinterpret_cast<u64>(code_address)); ZYAN_SUCCESS(status) ? ZydisMnemonicGetString(instruction.mnemonic)
} : "Failed to decode");
UNREACHABLE_MSG("Failed to patch address {:x} -- mnemonic: {}", return false;
reinterpret_cast<u64>(code_address),
ZYAN_SUCCESS(status) ? ZydisMnemonicGetString(instruction.mnemonic)
: "Failed to decode");
} }
} }

View File

@ -2,7 +2,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h" #include "common/assert.h"
#include "core/libraries/kernel/kernel.h"
#include "core/libraries/kernel/orbis_error.h" #include "core/libraries/kernel/orbis_error.h"
#include "core/libraries/kernel/posix_error.h"
#include "core/libraries/kernel/threads/exception.h" #include "core/libraries/kernel/threads/exception.h"
#include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/kernel/threads/pthread.h"
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
@ -13,23 +15,24 @@
#else #else
#include <csignal> #include <csignal>
#endif #endif
#include <unordered_set>
namespace Libraries::Kernel { namespace Libraries::Kernel {
#ifdef _WIN32 #ifdef _WIN32
// Windows doesn't have native versions of these, and we don't need to use them either. // Windows doesn't have native versions of these, and we don't need to use them either.
static s32 NativeToOrbisSignal(s32 s) { s32 NativeToOrbisSignal(s32 s) {
return s; return s;
} }
static s32 OrbisToNativeSignal(s32 s) { s32 OrbisToNativeSignal(s32 s) {
return s; return s;
} }
#else #else
static s32 NativeToOrbisSignal(s32 s) { s32 NativeToOrbisSignal(s32 s) {
switch (s) { switch (s) {
case SIGHUP: case SIGHUP:
return POSIX_SIGHUP; return POSIX_SIGHUP;
@ -89,12 +92,21 @@ static s32 NativeToOrbisSignal(s32 s) {
return POSIX_SIGUSR1; return POSIX_SIGUSR1;
case SIGUSR2: case SIGUSR2:
return POSIX_SIGUSR2; return POSIX_SIGUSR2;
case _SIGEMT:
return POSIX_SIGEMT;
case _SIGINFO:
return POSIX_SIGINFO;
case 0:
return 128;
default: default:
if (s > 0 && s < 128) {
return s;
}
UNREACHABLE_MSG("Unknown signal {}", s); UNREACHABLE_MSG("Unknown signal {}", s);
} }
} }
static s32 OrbisToNativeSignal(s32 s) { s32 OrbisToNativeSignal(s32 s) {
switch (s) { switch (s) {
case POSIX_SIGHUP: case POSIX_SIGHUP:
return SIGHUP; return SIGHUP;
@ -108,6 +120,8 @@ static s32 OrbisToNativeSignal(s32 s) {
return SIGTRAP; return SIGTRAP;
case POSIX_SIGABRT: case POSIX_SIGABRT:
return SIGABRT; return SIGABRT;
case POSIX_SIGEMT:
return _SIGEMT;
case POSIX_SIGFPE: case POSIX_SIGFPE:
return SIGFPE; return SIGFPE;
case POSIX_SIGKILL: case POSIX_SIGKILL:
@ -150,22 +164,33 @@ static s32 OrbisToNativeSignal(s32 s) {
return SIGPROF; return SIGPROF;
case POSIX_SIGWINCH: case POSIX_SIGWINCH:
return SIGWINCH; return SIGWINCH;
case POSIX_SIGINFO:
return _SIGINFO;
case POSIX_SIGUSR1: case POSIX_SIGUSR1:
return SIGUSR1; return SIGUSR1;
case POSIX_SIGUSR2: case POSIX_SIGUSR2:
return SIGUSR2; return SIGUSR2;
case 128:
return 0;
default: default:
if (s > 0 && s < 128) {
return s;
}
UNREACHABLE_MSG("Unknown signal {}", s); UNREACHABLE_MSG("Unknown signal {}", s);
} }
} }
#endif #endif
std::array<SceKernelExceptionHandler, 32> Handlers{}; #ifdef __APPLE__
#define sigisemptyset(x) (*(x) == 0)
#endif
std::array<OrbisKernelExceptionHandler, 130> Handlers{};
#ifndef _WIN64 #ifndef _WIN64
void SigactionHandler(int native_signum, siginfo_t* inf, ucontext_t* raw_context) { void SigactionHandler(int native_signum, siginfo_t* inf, ucontext_t* raw_context) {
const auto handler = Handlers[native_signum]; const auto handler = Handlers[NativeToOrbisSignal(native_signum)];
if (handler) { if (handler) {
auto ctx = Ucontext{}; auto ctx = Ucontext{};
#ifdef __APPLE__ #ifdef __APPLE__
@ -214,6 +239,8 @@ void SigactionHandler(int native_signum, siginfo_t* inf, ucontext_t* raw_context
ctx.uc_mcontext.mc_addr = reinterpret_cast<uint64_t>(inf->si_addr); ctx.uc_mcontext.mc_addr = reinterpret_cast<uint64_t>(inf->si_addr);
#endif #endif
handler(NativeToOrbisSignal(native_signum), &ctx); handler(NativeToOrbisSignal(native_signum), &ctx);
} else {
UNREACHABLE_MSG("Unhandled exception");
} }
} }
#else #else
@ -221,7 +248,7 @@ void ExceptionHandler(void* arg1, void* arg2, void* arg3, PCONTEXT context) {
const char* thrName = (char*)arg1; const char* thrName = (char*)arg1;
int native_signum = reinterpret_cast<uintptr_t>(arg2); int native_signum = reinterpret_cast<uintptr_t>(arg2);
LOG_INFO(Lib_Kernel, "Exception raised successfully on thread '{}'", thrName); LOG_INFO(Lib_Kernel, "Exception raised successfully on thread '{}'", thrName);
const auto handler = Handlers[native_signum]; const auto handler = Handlers[NativeToOrbisSignal(native_signum)];
if (handler) { if (handler) {
auto ctx = Ucontext{}; auto ctx = Ucontext{};
ctx.uc_mcontext.mc_r8 = context->R8; ctx.uc_mcontext.mc_r8 = context->R8;
@ -243,76 +270,105 @@ void ExceptionHandler(void* arg1, void* arg2, void* arg3, PCONTEXT context) {
ctx.uc_mcontext.mc_fs = context->SegFs; ctx.uc_mcontext.mc_fs = context->SegFs;
ctx.uc_mcontext.mc_gs = context->SegGs; ctx.uc_mcontext.mc_gs = context->SegGs;
handler(NativeToOrbisSignal(native_signum), &ctx); handler(NativeToOrbisSignal(native_signum), &ctx);
} else {
UNREACHABLE_MSG("Unhandled exception");
} }
} }
#endif #endif
int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelExceptionHandler handler) { s32 PS4_SYSV_ABI posix_sigemptyset(Sigset* s) {
if (signum > POSIX_SIGUSR2) { s->bits[0] = 0;
return ORBIS_KERNEL_ERROR_EINVAL; s->bits[1] = 0;
return 0;
}
bool PS4_SYSV_ABI posix_sigisemptyset(Sigset* s) {
return s->bits[0] == 0 && s->bits[1] == 0;
}
s32 PS4_SYSV_ABI posix_sigaction(s32 sig, Sigaction* act, Sigaction* oact) {
if (sig < 1 || sig > 128 || sig == POSIX_SIGTHR || sig == POSIX_SIGKILL ||
sig == POSIX_SIGSTOP) {
*__Error() = POSIX_EINVAL;
return ORBIS_FAIL;
}
#ifdef _WIN32
LOG_ERROR(Lib_Kernel, "(STUBBED) called, sig: {}", sig);
Handlers[sig] = reinterpret_cast<OrbisKernelExceptionHandler>(
act ? act->__sigaction_handler.sigaction : nullptr);
#else
s32 native_sig = OrbisToNativeSignal(sig);
if (native_sig == SIGVTALRM) {
LOG_ERROR(Lib_Kernel, "Guest is attempting to use the HLE-reserved signal {}!", sig);
*__Error() = POSIX_EINVAL;
return ORBIS_FAIL;
}
#ifndef __APPLE__
if (native_sig >= __SIGRTMIN && native_sig < SIGRTMIN) {
LOG_ERROR(Lib_Kernel, "Guest is attempting to use the HLE libc-reserved signal {}!", sig);
*__Error() = POSIX_EINVAL;
return ORBIS_FAIL;
}
#else
if (native_sig > SIGUSR2) {
LOG_ERROR(Lib_Kernel,
"Guest is attempting to use SIGRT signals, which aren't available on this "
"platform (signal: {})!",
sig);
} }
LOG_INFO(Lib_Kernel, "Installing signal handler for {}", signum);
int const native_signum = OrbisToNativeSignal(signum);
#ifdef __APPLE__
ASSERT_MSG(native_signum != SIGVTALRM, "SIGVTALRM is HLE-reserved on macOS!");
#endif #endif
ASSERT_MSG(!Handlers[native_signum], "Invalid parameters"); LOG_INFO(Lib_Kernel, "called, sig: {}, native sig: {}", sig, native_sig);
Handlers[native_signum] = handler; struct sigaction native_act{};
#ifndef _WIN64 if (act) {
if (native_signum == SIGSEGV || native_signum == SIGBUS || native_signum == SIGILL) { native_act.sa_flags = act->sa_flags; // todo check compatibility, on Linux it seems fine
native_act.sa_sigaction =
reinterpret_cast<decltype(native_act.sa_sigaction)>(SigactionHandler);
if (!posix_sigisemptyset(&act->sa_mask)) {
LOG_ERROR(Lib_Kernel, "Unhandled sa_mask: {:x}", act->sa_mask.bits[0]);
}
}
auto const prev_handler = Handlers[sig];
Handlers[sig] = reinterpret_cast<OrbisKernelExceptionHandler>(
act ? act->__sigaction_handler.sigaction : nullptr);
if (native_sig == SIGSEGV || native_sig == SIGBUS || native_sig == SIGILL) {
return ORBIS_OK; // These are handled in Core::SignalHandler return ORBIS_OK; // These are handled in Core::SignalHandler
} }
struct sigaction act = {}; if (native_sig > 127) {
act.sa_flags = SA_SIGINFO | SA_RESTART; LOG_WARNING(Lib_Kernel, "We can't install a handler for native signal {}!", native_sig);
act.sa_sigaction = reinterpret_cast<decltype(act.sa_sigaction)>(SigactionHandler); return ORBIS_OK;
sigemptyset(&act.sa_mask);
sigaction(native_signum, &act, nullptr);
#endif
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
if (signum > POSIX_SIGUSR2) {
return ORBIS_KERNEL_ERROR_EINVAL;
} }
int const native_signum = OrbisToNativeSignal(signum); struct sigaction native_oact{};
if (!Handlers[native_signum]) { s32 ret = sigaction(native_sig, act ? &native_act : nullptr, oact ? &native_oact : nullptr);
LOG_WARNING(Lib_Kernel, "removing non-installed handler for signum {}", signum); if (oact) {
return ORBIS_KERNEL_ERROR_EINVAL; oact->sa_flags = native_oact.sa_flags;
oact->__sigaction_handler.sigaction =
reinterpret_cast<decltype(oact->__sigaction_handler.sigaction)>(prev_handler);
if (!sigisemptyset(&native_oact.sa_mask)) {
LOG_ERROR(Lib_Kernel, "Unhandled sa_mask");
}
} }
Handlers[native_signum] = nullptr; if (ret < 0) {
#ifndef _WIN64 LOG_ERROR(Lib_Kernel, "sigaction failed: {}", strerror(errno));
if (native_signum == SIGSEGV || native_signum == SIGBUS || native_signum == SIGILL) { *__Error() = ErrnoToSceKernelError(errno);
struct sigaction action{}; return ORBIS_FAIL;
action.sa_sigaction = Core::SignalHandler;
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigemptyset(&action.sa_mask);
ASSERT_MSG(sigaction(native_signum, &action, nullptr) == 0,
"Failed to reinstate original signal handler for signal {}", native_signum);
} else {
struct sigaction act = {};
act.sa_flags = SA_SIGINFO | SA_RESTART;
act.sa_sigaction = nullptr;
sigemptyset(&act.sa_mask);
sigaction(native_signum, &act, nullptr);
} }
#endif #endif
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) { s32 PS4_SYSV_ABI posix_pthread_kill(PthreadT thread, s32 sig) {
if (signum != POSIX_SIGUSR1) { if (sig < 1 || sig > 128) { // off-by-one error?
return ORBIS_KERNEL_ERROR_EINVAL; return POSIX_EINVAL;
} }
LOG_WARNING(Lib_Kernel, "Raising exception on thread '{}'", thread->name); LOG_WARNING(Lib_Kernel, "Raising signal {} on thread '{}'", sig, thread->name);
int const native_signum = OrbisToNativeSignal(signum); int const native_signum = OrbisToNativeSignal(sig);
#ifndef _WIN64 #ifndef _WIN64
const auto pthr = reinterpret_cast<pthread_t>(thread->native_thr.GetHandle()); const auto pthr = reinterpret_cast<pthread_t>(thread->native_thr.GetHandle());
const auto ret = pthread_kill(pthr, native_signum); const auto ret = pthread_kill(pthr, native_signum);
if (ret != 0) { if (ret != 0) {
LOG_ERROR(Kernel, "Failed to send exception signal to thread '{}': {}", thread->name, LOG_ERROR(Kernel, "Failed to send exception signal to thread '{}': {}", thread->name,
strerror(ret)); strerror(errno));
} }
#else #else
USER_APC_OPTION option; USER_APC_OPTION option;
@ -326,6 +382,67 @@ int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
return ORBIS_OK; return ORBIS_OK;
} }
// libkernel has a check in sceKernelInstallExceptionHandler and sceKernelRemoveExceptionHandler for
// validating if the application requested a handler for an allowed signal or not. However, that is
// just a wrapper for sigaction, which itself does not have any such restrictions, and therefore
// this check is ridiculously trivial to go around. This, however, means that we need to support all
// 127 - 3 possible signals, even if realistically, only homebrew will use most of them.
static std::unordered_set<s32> orbis_allowed_signals{
POSIX_SIGHUP, POSIX_SIGILL, POSIX_SIGFPE, POSIX_SIGBUS, POSIX_SIGSEGV, POSIX_SIGUSR1,
};
int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, OrbisKernelExceptionHandler handler) {
if (!orbis_allowed_signals.contains(signum)) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
if (Handlers[signum] != nullptr) {
return ORBIS_KERNEL_ERROR_EAGAIN;
}
LOG_INFO(Lib_Kernel, "Installing signal handler for {}", signum);
Sigaction act = {};
act.sa_flags = POSIX_SA_SIGINFO | POSIX_SA_RESTART;
act.__sigaction_handler.sigaction =
reinterpret_cast<decltype(act.__sigaction_handler.sigaction)>(handler);
posix_sigemptyset(&act.sa_mask);
s32 ret = posix_sigaction(signum, &act, nullptr);
if (ret < 0) {
LOG_ERROR(Lib_Kernel, "Failed to add handler for signal {}: {}", signum,
strerror(*__Error()));
return ErrnoToSceKernelError(*__Error());
}
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
if (!orbis_allowed_signals.contains(signum)) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
int const native_signum = OrbisToNativeSignal(signum);
Handlers[signum] = nullptr;
Sigaction act = {};
act.sa_flags = POSIX_SA_SIGINFO;
act.__sigaction_handler.sigaction = nullptr;
posix_sigemptyset(&act.sa_mask);
s32 ret = posix_sigaction(signum, &act, nullptr);
if (ret < 0) {
LOG_ERROR(Lib_Kernel, "Failed to remove handler for signal {}: {}", signum,
strerror(*__Error()));
return ErrnoToSceKernelError(*__Error());
}
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
if (signum != POSIX_SIGUSR1) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
s32 ret = posix_pthread_kill(thread, signum);
if (ret < 0) {
return ErrnoToSceKernelError(ret);
}
return ret;
}
s32 PS4_SYSV_ABI sceKernelDebugRaiseException(s32 error, s64 unk) { s32 PS4_SYSV_ABI sceKernelDebugRaiseException(s32 error, s64 unk) {
if (unk != 0) { if (unk != 0) {
return ORBIS_KERNEL_ERROR_EINVAL; return ORBIS_KERNEL_ERROR_EINVAL;
@ -352,6 +469,13 @@ void RegisterException(Core::Loader::SymbolsResolver* sym) {
sceKernelDebugRaiseExceptionOnReleaseMode); sceKernelDebugRaiseExceptionOnReleaseMode);
LIB_FUNCTION("WkwEd3N7w0Y", "libkernel", 1, "libkernel", sceKernelInstallExceptionHandler); LIB_FUNCTION("WkwEd3N7w0Y", "libkernel", 1, "libkernel", sceKernelInstallExceptionHandler);
LIB_FUNCTION("Qhv5ARAoOEc", "libkernel", 1, "libkernel", sceKernelRemoveExceptionHandler); LIB_FUNCTION("Qhv5ARAoOEc", "libkernel", 1, "libkernel", sceKernelRemoveExceptionHandler);
LIB_FUNCTION("KiJEPEWRyUY", "libkernel", 1, "libkernel", posix_sigaction);
LIB_FUNCTION("+F7C-hdk7+E", "libkernel", 1, "libkernel", posix_sigemptyset);
LIB_FUNCTION("yH-uQW3LbX0", "libkernel", 1, "libkernel", posix_pthread_kill);
LIB_FUNCTION("KiJEPEWRyUY", "libScePosix", 1, "libkernel", posix_sigaction);
LIB_FUNCTION("+F7C-hdk7+E", "libScePosix", 1, "libkernel", posix_sigemptyset);
LIB_FUNCTION("yH-uQW3LbX0", "libScePosix", 1, "libkernel", posix_pthread_kill);
} }
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -11,7 +11,7 @@ class SymbolsResolver;
namespace Libraries::Kernel { namespace Libraries::Kernel {
using SceKernelExceptionHandler = PS4_SYSV_ABI void (*)(int, void*); using OrbisKernelExceptionHandler = PS4_SYSV_ABI void (*)(int, void*);
constexpr s32 POSIX_SIGHUP = 1; constexpr s32 POSIX_SIGHUP = 1;
constexpr s32 POSIX_SIGINT = 2; constexpr s32 POSIX_SIGINT = 2;
@ -47,6 +47,23 @@ constexpr s32 POSIX_SIGUSR2 = 31;
constexpr s32 POSIX_SIGTHR = 32; constexpr s32 POSIX_SIGTHR = 32;
constexpr s32 POSIX_SIGLIBRT = 33; constexpr s32 POSIX_SIGLIBRT = 33;
#ifdef __linux__
constexpr s32 _SIGEMT = 128;
constexpr s32 _SIGINFO = 129;
#elif !defined(_WIN32)
constexpr s32 _SIGEMT = SIGEMT;
constexpr s32 _SIGINFO = SIGINFO;
#endif
constexpr s32 POSIX_SA_NOCLDSTOP = 1;
constexpr s32 POSIX_SA_NOCLDWAIT = 2;
constexpr s32 POSIX_SA_SIGINFO = 4;
constexpr s32 POSIX_SA_ONSTACK = 0x08000000;
constexpr s32 POSIX_SA_RESTART = 0x10000000;
constexpr s32 POSIX_SA_NODEFER = 0x40000000;
constexpr s32 POSIX_SA_RESETHAND = 0x80000000;
constexpr s32 POSIX_SA_RESTORER = 0x04000000;
struct Mcontext { struct Mcontext {
u64 mc_onstack; u64 mc_onstack;
u64 mc_rdi; u64 mc_rdi;
@ -101,17 +118,74 @@ struct Sigset {
u64 bits[2]; u64 bits[2];
}; };
union Sigval {
/* Members as suggested by Annex C of POSIX 1003.1b. */
int sival_int;
void* sival_ptr;
/* 6.0 compatibility */
int sigval_int;
void* sigval_ptr;
};
struct Siginfo {
int _si_signo; /* signal number */
int _si_errno; /* errno association */
/*
* Cause of signal, one of the SI_ macros or signal-specific
* values, i.e. one of the FPE_... values for SIGFPE. This
* value is equivalent to the second argument to an old-style
* FreeBSD signal handler.
*/
int _si_code; /* signal code */
s32 _si_pid; /* sending process */
u32 _si_uid; /* sender's ruid */
int _si_status; /* exit value */
void* _si_addr; /* faulting instruction */
union Sigval _si_value; /* signal value */
union {
struct {
int _trapno; /* machine specific trap code */
} _fault;
struct {
int _timerid;
int _overrun;
} _timer;
struct {
int _mqd;
} _mesgq;
struct {
long _band; /* band event for SIGPOLL */
} _poll; /* was this ever used ? */
struct {
long __spare1__;
int __spare2__[7];
} __spare__;
} _reason;
};
struct Sigaction {
union {
void (*handler)(int);
void (*sigaction)(int, struct Siginfo*, void*);
} __sigaction_handler;
int sa_flags;
Sigset sa_mask;
};
struct Ucontext { struct Ucontext {
struct Sigset uc_sigmask; struct Sigset uc_sigmask;
int field1_0x10[12]; int field1_0x10[12];
struct Mcontext uc_mcontext; Mcontext uc_mcontext;
struct Ucontext* uc_link; Ucontext* uc_link;
struct ExStack uc_stack; ExStack uc_stack;
int uc_flags; int uc_flags;
int __spare[4]; int __spare[4];
int field7_0x4f4[3]; int field7_0x4f4[3];
}; };
s32 NativeToOrbisSignal(s32 s);
s32 OrbisToNativeSignal(s32 s);
void RegisterException(Core::Loader::SymbolsResolver* sym); void RegisterException(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -665,6 +665,7 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", posix_pthread_once); LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", posix_pthread_once);
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", posix_pthread_self); LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", posix_pthread_self);
LIB_FUNCTION("OxhIB8LB-PQ", "libkernel", 1, "libkernel", posix_pthread_create); LIB_FUNCTION("OxhIB8LB-PQ", "libkernel", 1, "libkernel", posix_pthread_create);
LIB_FUNCTION("Jmi+9w9u0E4", "libkernel", 1, "libkernel", posix_pthread_create_name_np);
LIB_FUNCTION("lZzFeSxPl08", "libkernel", 1, "libkernel", posix_pthread_setcancelstate); LIB_FUNCTION("lZzFeSxPl08", "libkernel", 1, "libkernel", posix_pthread_setcancelstate);
LIB_FUNCTION("CBNtXOoef-E", "libkernel", 1, "libkernel", posix_sched_get_priority_max); LIB_FUNCTION("CBNtXOoef-E", "libkernel", 1, "libkernel", posix_sched_get_priority_max);
LIB_FUNCTION("m0iS6jNsXds", "libkernel", 1, "libkernel", posix_sched_get_priority_min); LIB_FUNCTION("m0iS6jNsXds", "libkernel", 1, "libkernel", posix_sched_get_priority_min);

View File

@ -22,6 +22,10 @@
#include "core/tls.h" #include "core/tls.h"
#include "ipc/ipc.h" #include "ipc/ipc.h"
#ifndef _WIN32
#include <signal.h>
#endif
namespace Core { namespace Core {
static PS4_SYSV_ABI void ProgramExitFunc() { static PS4_SYSV_ABI void ProgramExitFunc() {
@ -107,6 +111,11 @@ void Linker::Execute(const std::vector<std::string>& args) {
main_thread.Run([this, module, &args](std::stop_token) { main_thread.Run([this, module, &args](std::stop_token) {
Common::SetCurrentThreadName("Game:Main"); Common::SetCurrentThreadName("Game:Main");
#ifndef _WIN32 // Clear any existing signal mask for game threads.
sigset_t emptyset;
sigemptyset(&emptyset);
pthread_sigmask(SIG_SETMASK, &emptyset, nullptr);
#endif
if (auto& ipc = IPC::Instance()) { if (auto& ipc = IPC::Instance()) {
ipc.WaitForStart(); ipc.WaitForStart();
} }

View File

@ -21,7 +21,7 @@
#ifndef _WIN32 #ifndef _WIN32
namespace Libraries::Kernel { namespace Libraries::Kernel {
void SigactionHandler(int native_signum, siginfo_t* inf, ucontext_t* raw_context); void SigactionHandler(int native_signum, siginfo_t* inf, ucontext_t* raw_context);
extern std::array<SceKernelExceptionHandler, 32> Handlers; extern std::array<OrbisKernelExceptionHandler, 32> Handlers;
} // namespace Libraries::Kernel } // namespace Libraries::Kernel
#endif #endif
@ -86,7 +86,7 @@ void SignalHandler(int sig, siginfo_t* info, void* raw_context) {
if (!signals->DispatchAccessViolation(raw_context, info->si_addr)) { if (!signals->DispatchAccessViolation(raw_context, info->si_addr)) {
// If the guest has installed a custom signal handler, and the access violation didn't // If the guest has installed a custom signal handler, and the access violation didn't
// come from HLE memory tracking, pass the signal on // come from HLE memory tracking, pass the signal on
if (Libraries::Kernel::Handlers[sig]) { if (Libraries::Kernel::Handlers[Libraries::Kernel::NativeToOrbisSignal(sig)]) {
Libraries::Kernel::SigactionHandler(sig, info, Libraries::Kernel::SigactionHandler(sig, info,
reinterpret_cast<ucontext_t*>(raw_context)); reinterpret_cast<ucontext_t*>(raw_context));
return; return;
@ -99,7 +99,7 @@ void SignalHandler(int sig, siginfo_t* info, void* raw_context) {
} }
case SIGILL: case SIGILL:
if (!signals->DispatchIllegalInstruction(raw_context)) { if (!signals->DispatchIllegalInstruction(raw_context)) {
if (Libraries::Kernel::Handlers[sig]) { if (Libraries::Kernel::Handlers[Libraries::Kernel::NativeToOrbisSignal(sig)]) {
Libraries::Kernel::SigactionHandler(sig, info, Libraries::Kernel::SigactionHandler(sig, info,
reinterpret_cast<ucontext_t*>(raw_context)); reinterpret_cast<ucontext_t*>(raw_context));
return; return;

View File

@ -10,10 +10,8 @@
#ifdef _WIN32 #ifdef _WIN32
#define SIGSLEEP -1 #define SIGSLEEP -1
#elif defined(__APPLE__)
#define SIGSLEEP SIGVTALRM
#else #else
#define SIGSLEEP SIGRTMAX #define SIGSLEEP SIGVTALRM
#endif #endif
namespace Core { namespace Core {