mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-06-05 15:55:01 -06:00
Lib.Kernel: Various (mostly signal-related) fixes (#4463)
* sigaddset, sigdelset, sigismember * Some define fixups Based on decomp, PS4 sigset is defined as a u32[4]. This doesn't change any behavior, but makes my decomp-based sigaddset and sigdelset implementations function appropriately. Additionally, define handler and sigaction functions as PS4_SYSV_ABI. * Fix returns * Implement signal, export _sigintr In libkernel, signal just uses sigaction. No harm in implementing it, since we've got our own implementations for everything except sigaction (and sigaction is implemented for Unix platforms). * Fix and cleanup posix_select defines Swaps use of defines for just having static functions, and fixes the pd_set_posix struct to match FreeBSD/Orbis properly (sizeof(long) == 4 on Windows, which does not match Orbis). * Fix siginfo struct Again, sizeof(long) differs on different platforms. Need to use our proper typedef to ensure accuracy. * Clang, the bane of my existance. * Oops
This commit is contained in:
parent
9dada49956
commit
86a64fb980
@ -1223,25 +1223,26 @@ s32 PS4_SYSV_ABI sceKernelUnlink(const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define __FD_SETSIZE 1024
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long fds_bits[__FD_SETSIZE / (8 * sizeof(unsigned long))];
|
u64 fds_bits[16];
|
||||||
} fd_set_posix;
|
} fd_set_posix;
|
||||||
|
|
||||||
#define FD_SET_POSIX(fd, set) \
|
static void FD_SET_POSIX(s32 fd, fd_set_posix* set) {
|
||||||
((set)->fds_bits[(fd) / (8 * sizeof(unsigned long))] |= \
|
set->fds_bits[fd / (8 * sizeof(u64))] |= (1ULL << (fd % (8 * sizeof(u64))));
|
||||||
(1UL << ((fd) % (8 * sizeof(unsigned long)))))
|
}
|
||||||
|
|
||||||
#define FD_CLR_POSIX(fd, set) \
|
static void FD_CLR_POSIX(s32 fd, fd_set_posix* set) {
|
||||||
((set)->fds_bits[(fd) / (8 * sizeof(unsigned long))] &= \
|
set->fds_bits[fd / (8 * sizeof(u64))] &= ~(1ULL << (fd % (8 * sizeof(u64))));
|
||||||
~(1UL << ((fd) % (8 * sizeof(unsigned long)))))
|
}
|
||||||
|
|
||||||
#define FD_ISSET_POSIX(fd, set) \
|
static bool FD_ISSET_POSIX(s32 fd, fd_set_posix* set) {
|
||||||
(((set)->fds_bits[(fd) / (8 * sizeof(unsigned long))] & \
|
return (set->fds_bits[fd / (8 * sizeof(u64))] & (1ULL << (fd % (8 * sizeof(u64))))) != 0;
|
||||||
(1UL << ((fd) % (8 * sizeof(unsigned long))))) != 0)
|
}
|
||||||
|
|
||||||
#define FD_ZERO_POSIX(set) memset((set), 0, sizeof(fd_set_posix))
|
static void FD_ZERO_POSIX(fd_set_posix* set) {
|
||||||
|
std::memset(set, 0, sizeof(fd_set_posix));
|
||||||
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI posix_select(s32 nfds, fd_set_posix* readfds, fd_set_posix* writefds,
|
s32 PS4_SYSV_ABI posix_select(s32 nfds, fd_set_posix* readfds, fd_set_posix* writefds,
|
||||||
fd_set_posix* exceptfds, OrbisKernelTimeval* timeout) {
|
fd_set_posix* exceptfds, OrbisKernelTimeval* timeout) {
|
||||||
|
|||||||
@ -187,6 +187,7 @@ s32 OrbisToNativeSignal(s32 s) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::array<OrbisKernelExceptionHandler, 130> Handlers{};
|
std::array<OrbisKernelExceptionHandler, 130> Handlers{};
|
||||||
|
Sigset g_sigintr{};
|
||||||
|
|
||||||
#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) {
|
||||||
@ -301,17 +302,50 @@ void ExceptionHandler(void* arg1, void* arg2, void* arg3, PCONTEXT context) {
|
|||||||
s32 PS4_SYSV_ABI posix_sigemptyset(Sigset* s) {
|
s32 PS4_SYSV_ABI posix_sigemptyset(Sigset* s) {
|
||||||
s->bits[0] = 0;
|
s->bits[0] = 0;
|
||||||
s->bits[1] = 0;
|
s->bits[1] = 0;
|
||||||
return 0;
|
s->bits[2] = 0;
|
||||||
|
s->bits[3] = 0;
|
||||||
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI posix_sigfillset(Sigset* s) {
|
s32 PS4_SYSV_ABI posix_sigfillset(Sigset* s) {
|
||||||
s->bits[0] = ~0U;
|
s->bits[0] = ~0U;
|
||||||
s->bits[1] = ~0U;
|
s->bits[1] = ~0U;
|
||||||
return 0;
|
s->bits[2] = ~0U;
|
||||||
|
s->bits[3] = ~0U;
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI posix_sigaddset(Sigset* s, s32 sig) {
|
||||||
|
s32 val = sig - 1;
|
||||||
|
if (val >= 0x80) {
|
||||||
|
*Libraries::Kernel::__Error() = POSIX_EINVAL;
|
||||||
|
return ORBIS_FAIL;
|
||||||
|
}
|
||||||
|
s->bits[val >> 5] |= 1 << (val & 0x1f);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI posix_sigdelset(Sigset* s, s32 sig) {
|
||||||
|
s32 val = sig - 1;
|
||||||
|
if (val >= 0x80) {
|
||||||
|
*Libraries::Kernel::__Error() = POSIX_EINVAL;
|
||||||
|
return ORBIS_FAIL;
|
||||||
|
}
|
||||||
|
s->bits[val >> 5] &= ~(1 << (val & 0x1f));
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI posix_sigismember(Sigset* s, s32 sig) {
|
||||||
|
s32 val = sig - 1;
|
||||||
|
if (val >= 0x80) {
|
||||||
|
*Libraries::Kernel::__Error() = POSIX_EINVAL;
|
||||||
|
return ORBIS_FAIL;
|
||||||
|
}
|
||||||
|
return ((s->bits[val >> 5] >> (val & 0x1f)) & 1) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PS4_SYSV_ABI posix_sigisemptyset(Sigset* s) {
|
bool PS4_SYSV_ABI posix_sigisemptyset(Sigset* s) {
|
||||||
return s->bits[0] == 0 && s->bits[1] == 0;
|
return s->bits[0] == 0 && s->bits[1] == 0 && s->bits[2] == 0 && s->bits[3] == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI posix_sigprocmask(s32 how, const Sigset* set, Sigset* oset) {
|
s32 PS4_SYSV_ABI posix_sigprocmask(s32 how, const Sigset* set, Sigset* oset) {
|
||||||
@ -412,6 +446,22 @@ s32 PS4_SYSV_ABI posix_sigaction(s32 sig, Sigaction* act, Sigaction* oact) {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SigHandler PS4_SYSV_ABI posix_signal(s32 sig, SigHandler func) {
|
||||||
|
Sigaction act{};
|
||||||
|
act.__sigaction_handler.handler = func;
|
||||||
|
posix_sigemptyset(&act.sa_mask);
|
||||||
|
act.sa_flags = 0;
|
||||||
|
if (posix_sigismember(&g_sigintr, sig) == 0) {
|
||||||
|
act.sa_flags |= POSIX_SA_RESTART;
|
||||||
|
}
|
||||||
|
Sigaction oact{};
|
||||||
|
s32 result = posix_sigaction(sig, &act, &oact);
|
||||||
|
if (result >= ORBIS_OK) {
|
||||||
|
return oact.__sigaction_handler.handler;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<SigHandler>(-1);
|
||||||
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI posix_pthread_kill(PthreadT thread, s32 sig) {
|
s32 PS4_SYSV_ABI posix_pthread_kill(PthreadT thread, s32 sig) {
|
||||||
if (sig < 1 || sig > 128) { // off-by-one error?
|
if (sig < 1 || sig > 128) { // off-by-one error?
|
||||||
return POSIX_EINVAL;
|
return POSIX_EINVAL;
|
||||||
@ -515,6 +565,8 @@ s32 PS4_SYSV_ABI sceKernelDebugRaiseExceptionOnReleaseMode(s32 error, s64 unk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegisterException(Core::Loader::SymbolsResolver* sym) {
|
void RegisterException(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
LIB_OBJ("nQVWJEGHObc", "libkernel", 1, "libkernel", &g_sigintr);
|
||||||
|
|
||||||
LIB_FUNCTION("il03nluKfMk", "libkernel_unity", 1, "libkernel", sceKernelRaiseException);
|
LIB_FUNCTION("il03nluKfMk", "libkernel_unity", 1, "libkernel", sceKernelRaiseException);
|
||||||
LIB_FUNCTION("WkwEd3N7w0Y", "libkernel_unity", 1, "libkernel",
|
LIB_FUNCTION("WkwEd3N7w0Y", "libkernel_unity", 1, "libkernel",
|
||||||
sceKernelInstallExceptionHandler);
|
sceKernelInstallExceptionHandler);
|
||||||
@ -526,15 +578,23 @@ void RegisterException(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("Qhv5ARAoOEc", "libkernel", 1, "libkernel", sceKernelRemoveExceptionHandler);
|
LIB_FUNCTION("Qhv5ARAoOEc", "libkernel", 1, "libkernel", sceKernelRemoveExceptionHandler);
|
||||||
|
|
||||||
LIB_FUNCTION("KiJEPEWRyUY", "libkernel", 1, "libkernel", posix_sigaction);
|
LIB_FUNCTION("KiJEPEWRyUY", "libkernel", 1, "libkernel", posix_sigaction);
|
||||||
|
LIB_FUNCTION("VADc3MNQ3cM", "libkernel", 1, "libkernel", posix_signal);
|
||||||
LIB_FUNCTION("+F7C-hdk7+E", "libkernel", 1, "libkernel", posix_sigemptyset);
|
LIB_FUNCTION("+F7C-hdk7+E", "libkernel", 1, "libkernel", posix_sigemptyset);
|
||||||
LIB_FUNCTION("VkTAsrZDcJ0", "libkernel", 1, "libkernel", posix_sigfillset);
|
LIB_FUNCTION("VkTAsrZDcJ0", "libkernel", 1, "libkernel", posix_sigfillset);
|
||||||
|
LIB_FUNCTION("JUimFtKe0Kc", "libkernel", 1, "libkernel", posix_sigaddset);
|
||||||
|
LIB_FUNCTION("Nd-u09VFSCA", "libkernel", 1, "libkernel", posix_sigdelset);
|
||||||
|
LIB_FUNCTION("JnNl8Xr-z4Y", "libkernel", 1, "libkernel", posix_sigismember);
|
||||||
LIB_FUNCTION("aPcyptbOiZs", "libkernel", 1, "libkernel", posix_sigprocmask);
|
LIB_FUNCTION("aPcyptbOiZs", "libkernel", 1, "libkernel", posix_sigprocmask);
|
||||||
LIB_FUNCTION("yH-uQW3LbX0", "libkernel", 1, "libkernel", posix_pthread_kill);
|
LIB_FUNCTION("yH-uQW3LbX0", "libkernel", 1, "libkernel", posix_pthread_kill);
|
||||||
LIB_FUNCTION("sHziAegVp74", "libkernel", 1, "libkernel", posix_sigalstack);
|
LIB_FUNCTION("sHziAegVp74", "libkernel", 1, "libkernel", posix_sigalstack);
|
||||||
|
|
||||||
LIB_FUNCTION("KiJEPEWRyUY", "libScePosix", 1, "libkernel", posix_sigaction);
|
LIB_FUNCTION("KiJEPEWRyUY", "libScePosix", 1, "libkernel", posix_sigaction);
|
||||||
|
LIB_FUNCTION("VADc3MNQ3cM", "libScePosix", 1, "libkernel", posix_signal);
|
||||||
LIB_FUNCTION("+F7C-hdk7+E", "libScePosix", 1, "libkernel", posix_sigemptyset);
|
LIB_FUNCTION("+F7C-hdk7+E", "libScePosix", 1, "libkernel", posix_sigemptyset);
|
||||||
LIB_FUNCTION("VkTAsrZDcJ0", "libScePosix", 1, "libkernel", posix_sigfillset);
|
LIB_FUNCTION("VkTAsrZDcJ0", "libScePosix", 1, "libkernel", posix_sigfillset);
|
||||||
|
LIB_FUNCTION("JUimFtKe0Kc", "libScePosix", 1, "libkernel", posix_sigaddset);
|
||||||
|
LIB_FUNCTION("Nd-u09VFSCA", "libScePosix", 1, "libkernel", posix_sigdelset);
|
||||||
|
LIB_FUNCTION("JnNl8Xr-z4Y", "libScePosix", 1, "libkernel", posix_sigismember);
|
||||||
LIB_FUNCTION("aPcyptbOiZs", "libScePosix", 1, "libkernel", posix_sigprocmask);
|
LIB_FUNCTION("aPcyptbOiZs", "libScePosix", 1, "libkernel", posix_sigprocmask);
|
||||||
LIB_FUNCTION("yH-uQW3LbX0", "libScePosix", 1, "libkernel", posix_pthread_kill);
|
LIB_FUNCTION("yH-uQW3LbX0", "libScePosix", 1, "libkernel", posix_pthread_kill);
|
||||||
LIB_FUNCTION("sHziAegVp74", "libScePosix", 1, "libkernel", posix_sigalstack);
|
LIB_FUNCTION("sHziAegVp74", "libScePosix", 1, "libkernel", posix_sigalstack);
|
||||||
|
|||||||
@ -120,7 +120,7 @@ struct ExStack {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Sigset {
|
struct Sigset {
|
||||||
u64 bits[2];
|
u32 bits[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
union Sigval {
|
union Sigval {
|
||||||
@ -133,45 +133,47 @@ union Sigval {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Siginfo {
|
struct Siginfo {
|
||||||
int _si_signo; /* signal number */
|
s32 _si_signo; /* signal number */
|
||||||
int _si_errno; /* errno association */
|
s32 _si_errno; /* errno association */
|
||||||
/*
|
/*
|
||||||
* Cause of signal, one of the SI_ macros or signal-specific
|
* Cause of signal, one of the SI_ macros or signal-specific
|
||||||
* values, i.e. one of the FPE_... values for SIGFPE. This
|
* values, i.e. one of the FPE_... values for SIGFPE. This
|
||||||
* value is equivalent to the second argument to an old-style
|
* value is equivalent to the second argument to an old-style
|
||||||
* FreeBSD signal handler.
|
* FreeBSD signal handler.
|
||||||
*/
|
*/
|
||||||
int _si_code; /* signal code */
|
s32 _si_code; /* signal code */
|
||||||
s32 _si_pid; /* sending process */
|
s32 _si_pid; /* sending process */
|
||||||
u32 _si_uid; /* sender's ruid */
|
u32 _si_uid; /* sender's ruid */
|
||||||
int _si_status; /* exit value */
|
s32 _si_status; /* exit value */
|
||||||
void* _si_addr; /* faulting instruction */
|
void* _si_addr; /* faulting instruction */
|
||||||
union Sigval _si_value; /* signal value */
|
union Sigval _si_value; /* signal value */
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
int _trapno; /* machine specific trap code */
|
s32 _trapno; /* machine specific trap code */
|
||||||
} _fault;
|
} _fault;
|
||||||
struct {
|
struct {
|
||||||
int _timerid;
|
s32 _timerid;
|
||||||
int _overrun;
|
s32 _overrun;
|
||||||
} _timer;
|
} _timer;
|
||||||
struct {
|
struct {
|
||||||
int _mqd;
|
s32 _mqd;
|
||||||
} _mesgq;
|
} _mesgq;
|
||||||
struct {
|
struct {
|
||||||
long _band; /* band event for SIGPOLL */
|
s64 _band; /* band event for SIGPOLL */
|
||||||
} _poll; /* was this ever used ? */
|
} _poll; /* was this ever used ? */
|
||||||
struct {
|
struct {
|
||||||
long __spare1__;
|
s64 __spare1__;
|
||||||
int __spare2__[7];
|
s32 __spare2__[7];
|
||||||
} __spare__;
|
} __spare__;
|
||||||
} _reason;
|
} _reason;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using SigHandler = void PS4_SYSV_ABI (*)(int);
|
||||||
|
|
||||||
struct Sigaction {
|
struct Sigaction {
|
||||||
union {
|
union {
|
||||||
void (*handler)(int);
|
void PS4_SYSV_ABI (*handler)(int);
|
||||||
void (*sigaction)(int, struct Siginfo*, void*);
|
void PS4_SYSV_ABI (*sigaction)(int, struct Siginfo*, void*);
|
||||||
} __sigaction_handler;
|
} __sigaction_handler;
|
||||||
int sa_flags;
|
int sa_flags;
|
||||||
Sigset sa_mask;
|
Sigset sa_mask;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user