mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-01 12:46:01 +00:00
kernel: Add basic exceptions for linux
This commit is contained in:
parent
ef3341c78c
commit
cef37be33d
|
@ -210,6 +210,8 @@ set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp
|
|||
|
||||
set(KERNEL_LIB src/core/libraries/kernel/threads/condvar.cpp
|
||||
src/core/libraries/kernel/threads/event_flag.cpp
|
||||
src/core/libraries/kernel/threads/exception.cpp
|
||||
src/core/libraries/kernel/threads/exception.h
|
||||
src/core/libraries/kernel/threads/mutex.cpp
|
||||
src/core/libraries/kernel/threads/pthread_attr.cpp
|
||||
src/core/libraries/kernel/threads/pthread_clean.cpp
|
||||
|
|
|
@ -376,9 +376,12 @@ int PS4_SYSV_ABI sceGnmAreSubmitsAllowed() {
|
|||
return submission_lock == 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceGnmBeginWorkload() {
|
||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
int PS4_SYSV_ABI sceGnmBeginWorkload(uint param_1, ulong* param_2) {
|
||||
if (param_2 != (ulong*)0x0) {
|
||||
*param_2 = (ulong)(-(uint)(param_1 < 0x10) & 1);
|
||||
return 0xf < param_1;
|
||||
}
|
||||
return (bool)3;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceGnmComputeWaitOnAddress(u32* cmdbuf, u32 size, uintptr_t addr, u32 mask,
|
||||
|
@ -951,9 +954,11 @@ int PS4_SYSV_ABI sceGnmDriverTriggerCapture() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceGnmEndWorkload() {
|
||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
int PS4_SYSV_ABI sceGnmEndWorkload(long param_1) {
|
||||
if (param_1 != 0) {
|
||||
return (0xf < (u8)((ulong)param_1 >> 0x38)) * 2;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceGnmFindResourcesPublic() {
|
||||
|
|
|
@ -16,7 +16,7 @@ using namespace Kernel;
|
|||
|
||||
s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata);
|
||||
int PS4_SYSV_ABI sceGnmAreSubmitsAllowed();
|
||||
int PS4_SYSV_ABI sceGnmBeginWorkload();
|
||||
int PS4_SYSV_ABI sceGnmBeginWorkload(uint param_1, ulong* param_2);
|
||||
s32 PS4_SYSV_ABI sceGnmComputeWaitOnAddress(u32* cmdbuf, u32 size, uintptr_t addr, u32 mask,
|
||||
u32 cmp_func, u32 ref);
|
||||
int PS4_SYSV_ABI sceGnmComputeWaitSemaphore();
|
||||
|
@ -77,7 +77,7 @@ int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForValidation();
|
|||
int PS4_SYSV_ABI sceGnmDriverInternalVirtualQuery();
|
||||
int PS4_SYSV_ABI sceGnmDriverTraceInProgress();
|
||||
int PS4_SYSV_ABI sceGnmDriverTriggerCapture();
|
||||
int PS4_SYSV_ABI sceGnmEndWorkload();
|
||||
int PS4_SYSV_ABI sceGnmEndWorkload(long param_1);
|
||||
s32 PS4_SYSV_ABI sceGnmFindResourcesPublic();
|
||||
void PS4_SYSV_ABI sceGnmFlushGarlic();
|
||||
int PS4_SYSV_ABI sceGnmGetCoredumpAddress();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "core/libraries/kernel/memory.h"
|
||||
#include "core/libraries/kernel/process.h"
|
||||
#include "core/libraries/kernel/threads.h"
|
||||
#include "core/libraries/kernel/threads/exception.h"
|
||||
#include "core/libraries/kernel/time.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/linker.h"
|
||||
|
@ -153,17 +154,17 @@ void PS4_SYSV_ABI sceLibcHeapGetTraceInfo(HeapInfoInfo* info) {
|
|||
info->getSegmentInfo = 0;
|
||||
}
|
||||
|
||||
s64 PS4_SYSV_ABI ps4__write(int d, const void* buf, std::size_t nbytes) {
|
||||
s64 PS4_SYSV_ABI ps4__write(int d, const char* buf, std::size_t nbytes) {
|
||||
if (d <= 2) { // stdin,stdout,stderr
|
||||
char* str = strdup((const char*)buf);
|
||||
if (str[nbytes - 1] == '\n')
|
||||
str[nbytes - 1] = 0;
|
||||
std::string_view str{buf};
|
||||
if (str[nbytes - 1] == '\n') {
|
||||
str = str.substr(0, nbytes - 1);
|
||||
}
|
||||
LOG_INFO(Tty, "{}", str);
|
||||
free(str);
|
||||
return nbytes;
|
||||
}
|
||||
LOG_ERROR(Kernel, "(STUBBED) called d = {} nbytes = {} ", d, nbytes);
|
||||
UNREACHABLE(); // normal write , is it a posix call??
|
||||
UNREACHABLE();
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -330,6 +331,7 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
|
|||
Libraries::Kernel::RegisterMemory(sym);
|
||||
Libraries::Kernel::RegisterEventQueue(sym);
|
||||
Libraries::Kernel::RegisterProcess(sym);
|
||||
Libraries::Kernel::RegisterException(sym);
|
||||
|
||||
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
||||
LIB_FUNCTION("JGfTMBOdUJo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetFsSandboxRandomWord);
|
||||
|
|
|
@ -37,6 +37,7 @@ struct WrapperImpl<name, PS4_SYSV_ABI R (*)(Args...), f> {
|
|||
static R PS4_SYSV_ABI wrap(Args... args) {
|
||||
u32 ret = f(args...);
|
||||
if (ret != 0) {
|
||||
LOG_ERROR(Lib_Kernel, "Function {} returned {}", std::string_view{name.value}, ret);
|
||||
ret += SCE_KERNEL_ERROR_UNKNOWN;
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -219,6 +219,7 @@ int PS4_SYSV_ABI posix_pthread_condattr_setpshared(PthreadCondAttrT* attr, int p
|
|||
|
||||
void RegisterCond(Core::Loader::SymbolsResolver* sym) {
|
||||
// Posix
|
||||
LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_condattr_init);
|
||||
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
|
||||
LIB_FUNCTION("2MOy+rUfuhQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_signal);
|
||||
LIB_FUNCTION("RXXqi4CtF8w", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_destroy);
|
||||
|
|
102
src/core/libraries/kernel/threads/exception.cpp
Normal file
102
src/core/libraries/kernel/threads/exception.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/libraries/kernel/threads/exception.h"
|
||||
#include "core/libraries/kernel/threads/pthread.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
#else
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
static std::array<SceKernelExceptionHandler, 32> Handlers{};
|
||||
|
||||
void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) {
|
||||
const auto handler = Handlers[POSIX_SIGUSR1];
|
||||
if (handler) {
|
||||
auto ctx = Ucontext{};
|
||||
auto& regs = raw_context->uc_mcontext.gregs;
|
||||
ctx.uc_mcontext.mc_r8 = regs[REG_R8];
|
||||
ctx.uc_mcontext.mc_r9 = regs[REG_R9];
|
||||
ctx.uc_mcontext.mc_r10 = regs[REG_R10];
|
||||
ctx.uc_mcontext.mc_r11 = regs[REG_R11];
|
||||
ctx.uc_mcontext.mc_r12 = regs[REG_R12];
|
||||
ctx.uc_mcontext.mc_r13 = regs[REG_R13];
|
||||
ctx.uc_mcontext.mc_r14 = regs[REG_R14];
|
||||
ctx.uc_mcontext.mc_r15 = regs[REG_R15];
|
||||
ctx.uc_mcontext.mc_rdi = regs[REG_RDI];
|
||||
ctx.uc_mcontext.mc_rsi = regs[REG_RSI];
|
||||
ctx.uc_mcontext.mc_rbp = regs[REG_RBP];
|
||||
ctx.uc_mcontext.mc_rbx = regs[REG_RBX];
|
||||
ctx.uc_mcontext.mc_rdx = regs[REG_RDX];
|
||||
ctx.uc_mcontext.mc_rax = regs[REG_RAX];
|
||||
ctx.uc_mcontext.mc_rcx = regs[REG_RCX];
|
||||
ctx.uc_mcontext.mc_rsp = regs[REG_RSP];
|
||||
ctx.uc_mcontext.mc_fs = (regs[REG_CSGSFS] >> 32) & 0xFFFF;
|
||||
ctx.uc_mcontext.mc_gs = (regs[REG_CSGSFS] >> 16) & 0xFFFF;
|
||||
handler(POSIX_SIGUSR1, &ctx);
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelExceptionHandler handler) {
|
||||
if (signum == POSIX_SIGSEGV) {
|
||||
return 0;
|
||||
}
|
||||
ASSERT_MSG(signum == POSIX_SIGUSR1 && !Handlers[POSIX_SIGUSR1], "Invalid parameters");
|
||||
Handlers[POSIX_SIGUSR1] = handler;
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE_MSG("Missing exception implementation");
|
||||
#else
|
||||
struct sigaction act = {};
|
||||
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
act.sa_sigaction = reinterpret_cast<decltype(act.sa_sigaction)>(SigactionHandler);
|
||||
sigaction(SIGUSR2, &act, nullptr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) {
|
||||
if (signum == 8) {
|
||||
return 0;
|
||||
}
|
||||
ASSERT_MSG(signum == POSIX_SIGUSR1 && Handlers[POSIX_SIGUSR1], "Invalid parameters");
|
||||
Handlers[POSIX_SIGUSR1] = nullptr;
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE_MSG("Missing exception implementation");
|
||||
#else
|
||||
struct sigaction act = {};
|
||||
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
act.sa_sigaction = nullptr;
|
||||
sigaction(SIGUSR2, &act, nullptr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::mutex mtx;
|
||||
|
||||
int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
|
||||
std::scoped_lock lk{mtx};
|
||||
LOG_ERROR(Lib_Kernel, "Raising exception");
|
||||
ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!");
|
||||
#ifdef _WIN64
|
||||
UNREACHABLE("Missing exception implementation");
|
||||
#else
|
||||
pthread_t pthr = *reinterpret_cast<pthread_t*>(thread->native_handle);
|
||||
pthread_kill(pthr, SIGUSR2);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RegisterException(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("il03nluKfMk", "libkernel_unity", 1, "libkernel", 1, 1, sceKernelRaiseException);
|
||||
LIB_FUNCTION("WkwEd3N7w0Y", "libkernel_unity", 1, "libkernel", 1, 1,
|
||||
sceKernelInstallExceptionHandler);
|
||||
LIB_FUNCTION("Qhv5ARAoOEc", "libkernel_unity", 1, "libkernel", 1, 1,
|
||||
sceKernelRemoveExceptionHandler)
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
86
src/core/libraries/kernel/threads/exception.h
Normal file
86
src/core/libraries/kernel/threads/exception.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
using SceKernelExceptionHandler = PS4_SYSV_ABI void (*)(int, void*);
|
||||
|
||||
constexpr int POSIX_SIGSEGV = 11;
|
||||
constexpr int POSIX_SIGUSR1 = 30;
|
||||
|
||||
struct Mcontext {
|
||||
u64 mc_onstack;
|
||||
u64 mc_rdi;
|
||||
u64 mc_rsi;
|
||||
u64 mc_rdx;
|
||||
u64 mc_rcx;
|
||||
u64 mc_r8;
|
||||
u64 mc_r9;
|
||||
u64 mc_rax;
|
||||
u64 mc_rbx;
|
||||
u64 mc_rbp;
|
||||
u64 mc_r10;
|
||||
u64 mc_r11;
|
||||
u64 mc_r12;
|
||||
u64 mc_r13;
|
||||
u64 mc_r14;
|
||||
u64 mc_r15;
|
||||
int mc_trapno;
|
||||
u16 mc_fs;
|
||||
u16 mc_gs;
|
||||
u64 mc_addr;
|
||||
int mc_flags;
|
||||
u16 mc_es;
|
||||
u16 mc_ds;
|
||||
u64 mc_err;
|
||||
u64 mc_rip;
|
||||
u64 mc_cs;
|
||||
u64 mc_rflags;
|
||||
u64 mc_rsp;
|
||||
u64 mc_ss;
|
||||
u64 mc_len;
|
||||
u64 mc_fpformat;
|
||||
u64 mc_ownedfp;
|
||||
u64 mc_lbrfrom;
|
||||
u64 mc_lbrto;
|
||||
u64 mc_aux1;
|
||||
u64 mc_aux2;
|
||||
u64 mc_fpstate[104];
|
||||
u64 mc_fsbase;
|
||||
u64 mc_gsbase;
|
||||
u64 mc_spare[6];
|
||||
};
|
||||
|
||||
struct Stack {
|
||||
void* ss_sp;
|
||||
std::size_t ss_size;
|
||||
int ss_flags;
|
||||
int _align;
|
||||
};
|
||||
|
||||
struct Sigset {
|
||||
u64 bits[2];
|
||||
};
|
||||
|
||||
struct Ucontext {
|
||||
struct Sigset uc_sigmask;
|
||||
int field1_0x10[12];
|
||||
struct Mcontext uc_mcontext;
|
||||
struct Ucontext* uc_link;
|
||||
struct Stack uc_stack;
|
||||
int uc_flags;
|
||||
int __spare[4];
|
||||
int field7_0x4f4[3];
|
||||
};
|
||||
|
||||
void RegisterException(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
} // namespace Libraries::Kernel
|
|
@ -281,12 +281,11 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(PthreadT* thread, const PthreadAtt
|
|||
(*thread) = new_thread;
|
||||
|
||||
/* Create thread */
|
||||
pthread_t pthr;
|
||||
pthread_t* pthr = reinterpret_cast<pthread_t*>(&new_thread->native_handle);
|
||||
pthread_attr_t pattr;
|
||||
pthread_attr_init(&pattr);
|
||||
// pthread_attr_setstack(&pattr, new_thread->attr.stackaddr_attr,
|
||||
// new_thread->attr.stacksize_attr);
|
||||
int ret = pthread_create(&pthr, &pattr, (PthreadEntryFunc)RunThread, new_thread);
|
||||
pthread_attr_setstack(&pattr, new_thread->attr.stackaddr_attr, new_thread->attr.stacksize_attr);
|
||||
int ret = pthread_create(pthr, &pattr, (PthreadEntryFunc)RunThread, new_thread);
|
||||
ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret);
|
||||
if (ret) {
|
||||
*thread = nullptr;
|
||||
|
@ -303,6 +302,11 @@ int PS4_SYSV_ABI posix_pthread_getthreadid_np() {
|
|||
return g_curthread->tid;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_getname_np(PthreadT thread, char* name) {
|
||||
std::memcpy(name, thread->name.data(), std::min(thread->name.size(), 32UL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_equal(PthreadT thread1, PthreadT thread2) {
|
||||
return (thread1 == thread2 ? 1 : 0);
|
||||
}
|
||||
|
@ -417,13 +421,42 @@ int PS4_SYSV_ABI scePthreadGetprio(PthreadT thread, int* priority) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sceNpWebApiTerminate() {
|
||||
enum class PthreadCancelState : u32 {
|
||||
Enable = 0,
|
||||
Disable = 1,
|
||||
};
|
||||
|
||||
#define POSIX_PTHREAD_CANCELED ((void*)1)
|
||||
|
||||
static inline void TestCancel(Pthread* curthread) {
|
||||
if (curthread->ShouldCancel() && !curthread->InCritical()) [[unlikely]] {
|
||||
posix_pthread_exit(POSIX_PTHREAD_CANCELED);
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_setcancelstate(PthreadCancelState state,
|
||||
PthreadCancelState* oldstate) {
|
||||
Pthread* curthread = g_curthread;
|
||||
int oldval = curthread->cancel_enable;
|
||||
switch (state) {
|
||||
case PthreadCancelState::Disable:
|
||||
curthread->cancel_enable = 0;
|
||||
break;
|
||||
case PthreadCancelState::Enable:
|
||||
curthread->cancel_enable = 1;
|
||||
TestCancel(curthread);
|
||||
break;
|
||||
default:
|
||||
return POSIX_EINVAL;
|
||||
}
|
||||
|
||||
if (oldstate) {
|
||||
*oldstate = oldval ? PthreadCancelState::Enable : PthreadCancelState::Disable;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("asz3TtIqGF8", "libSceNpWebApi", 1, "libSceNpWebApi", 1, 1, sceNpWebApiTerminate);
|
||||
|
||||
// Posix
|
||||
LIB_FUNCTION("Z4QosVuAsA0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_once);
|
||||
LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_equal);
|
||||
|
@ -436,6 +469,7 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("h9CcP3J0oVM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_join);
|
||||
LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create);
|
||||
LIB_FUNCTION("Jmi+9w9u0E4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create_name_np);
|
||||
LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate);
|
||||
|
||||
// Posix-Kernel
|
||||
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
|
||||
|
@ -448,6 +482,9 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) {
|
|||
ORBIS(posix_pthread_create_name_np));
|
||||
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_detach));
|
||||
LIB_FUNCTION("onNY9Byn-W8", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_join));
|
||||
LIB_FUNCTION("P41kTWUS3EI", "libkernel", 1, "libkernel", 1, 1,
|
||||
ORBIS(posix_pthread_getschedparam));
|
||||
LIB_FUNCTION("How7B8Oet6k", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_getname_np));
|
||||
LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, posix_pthread_exit);
|
||||
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
|
||||
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_equal);
|
||||
|
|
|
@ -255,6 +255,7 @@ struct Pthread {
|
|||
int refcount;
|
||||
void* PS4_SYSV_ABI (*start_routine)(void*);
|
||||
void* arg;
|
||||
uintptr_t native_handle;
|
||||
PthreadAttr attr;
|
||||
bool cancel_enable;
|
||||
bool cancel_pending;
|
||||
|
|
|
@ -298,6 +298,8 @@ void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) {
|
|||
posix_pthread_attr_setinheritsched);
|
||||
LIB_FUNCTION("0qOtCR-ZHck", "libScePosix", 1, "libkernel", 1, 1,
|
||||
posix_pthread_attr_getstacksize);
|
||||
LIB_FUNCTION("VUT1ZSrHT0I", "libScePosix", 1, "libkernel", 1, 1,
|
||||
posix_pthread_attr_getdetachstate);
|
||||
|
||||
// Orbis
|
||||
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1,
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
void PS4_SYSV_ABI __pthread_cleanup_push_imp(PthreadCleanupFunc routine, void* arg, PthreadCleanup* newbuf) {
|
||||
void PS4_SYSV_ABI __pthread_cleanup_push_imp(PthreadCleanupFunc routine, void* arg,
|
||||
PthreadCleanup* newbuf) {
|
||||
newbuf->routine = routine;
|
||||
newbuf->routine_arg = arg;
|
||||
newbuf->onheap = 0;
|
||||
|
|
|
@ -142,6 +142,7 @@ const void* PS4_SYSV_ABI posix_pthread_getspecific(PthreadKeyT key) {
|
|||
void RegisterSpec(Core::Loader::SymbolsResolver* sym) {
|
||||
// Posix
|
||||
LIB_FUNCTION("mqULNdimTn0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_key_create);
|
||||
LIB_FUNCTION("6BpEZuDT7YI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_key_delete);
|
||||
LIB_FUNCTION("0-KXaS70xy4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_getspecific);
|
||||
LIB_FUNCTION("WrOLvHU0yQM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setspecific);
|
||||
|
||||
|
|
|
@ -9,7 +9,46 @@
|
|||
#include "core/loader/elf.h"
|
||||
#include "core/loader/symbols_resolver.h"
|
||||
|
||||
#define LIB_FUNCTION(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \
|
||||
template <size_t N>
|
||||
struct StringLiteral {
|
||||
constexpr StringLiteral(const char (&str)[N]) {
|
||||
std::copy_n(str, N, value);
|
||||
}
|
||||
|
||||
char value[N];
|
||||
};
|
||||
|
||||
template <StringLiteral name, class F, F f>
|
||||
struct wrapper_impl;
|
||||
|
||||
template <StringLiteral name, class R, class... Args, PS4_SYSV_ABI R (*f)(Args...)>
|
||||
struct wrapper_impl<name, PS4_SYSV_ABI R (*)(Args...), f> {
|
||||
static R PS4_SYSV_ABI wrap(Args... args) {
|
||||
if (std::string_view(name.value) != "scePthreadEqual" &&
|
||||
std::string_view(name.value) != "sceUserServiceGetEvent" &&
|
||||
!std::string_view(name.value).contains("scePthreadMutex") &&
|
||||
!std::string_view(name.value).contains("pthread_mutex")) {
|
||||
// LOG_WARNING(Core_Linker, "Function {} called", name.value);
|
||||
}
|
||||
if constexpr (std::is_same_v<R, s32> || std::is_same_v<R, u32>) {
|
||||
const u32 ret = f(args...);
|
||||
if (ret != 0 && !std::string_view(name.value).contains("pthread_equal")) {
|
||||
LOG_WARNING(Core_Linker, "Function {} returned {:#x}", name.value, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// stuff
|
||||
return f(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template <StringLiteral name, class F, F f>
|
||||
constexpr auto wrapper = wrapper_impl<name, F, f>::wrap;
|
||||
|
||||
#define W(foo) wrapper<#foo, decltype(&foo), foo>
|
||||
// #define W(foo) foo
|
||||
|
||||
#define LIB_FUNCTION(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, f) \
|
||||
{ \
|
||||
Core::Loader::SymbolResolver sr{}; \
|
||||
sr.name = nid; \
|
||||
|
@ -19,8 +58,10 @@
|
|||
sr.module_version_major = moduleVersionMajor; \
|
||||
sr.module_version_minor = moduleVersionMinor; \
|
||||
sr.type = Core::Loader::SymbolType::Function; \
|
||||
auto func = reinterpret_cast<u64>(function); \
|
||||
sym->AddSymbol(sr, func); \
|
||||
{ \
|
||||
auto func = reinterpret_cast<u64>(wrapper<#f, decltype(&f), f>); \
|
||||
sym->AddSymbol(sr, func); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LIB_OBJ(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \
|
||||
|
|
|
@ -25,6 +25,7 @@ int PS4_SYSV_ABI scePadConnectPort() {
|
|||
int PS4_SYSV_ABI scePadDeviceClassGetExtendedInformation(
|
||||
s32 handle, OrbisPadDeviceClassExtendedInformation* pExtInfo) {
|
||||
LOG_ERROR(Lib_Pad, "(STUBBED) called");
|
||||
std::memset(pExtInfo, 0, sizeof(OrbisPadDeviceClassExtendedInformation));
|
||||
if (Config::getUseSpecialPad()) {
|
||||
pExtInfo->deviceClass = (OrbisPadDeviceClass)Config::getSpecialPadClass();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma clang optimize off
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
#include "common/logging/log.h"
|
||||
|
@ -95,7 +95,7 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co
|
|||
LOG_ERROR(Lib_VideoOut, "Addresses are null");
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
VAddr ret_addr = (VAddr)__builtin_return_address(0);
|
||||
|
||||
auto* port = driver->GetPort(handle);
|
||||
if (!port || !port->is_open) {
|
||||
LOG_ERROR(Lib_VideoOut, "Invalid handle = {}", handle);
|
||||
|
|
|
@ -284,7 +284,7 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) {
|
|||
const u32 old_num_dtvs = dtv_table[1].counter;
|
||||
ASSERT_MSG(max_tls_index > old_num_dtvs, "Module unloading unsupported");
|
||||
// Module was loaded, increase DTV table size.
|
||||
DtvEntry* new_dtv_table = new DtvEntry[max_tls_index + 2];
|
||||
DtvEntry* new_dtv_table = new DtvEntry[max_tls_index + 2]{};
|
||||
std::memcpy(new_dtv_table + 2, dtv_table + 2, old_num_dtvs * sizeof(DtvEntry));
|
||||
new_dtv_table[0].counter = dtv_generation_counter;
|
||||
new_dtv_table[1].counter = max_tls_index;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma clang optimize off
|
||||
#include <cryptopp/sha.h>
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/arch.h"
|
||||
|
@ -56,6 +58,30 @@ static std::string EncodeId(u64 nVal) {
|
|||
return enc;
|
||||
}
|
||||
|
||||
static std::string StringToNid(std::string_view symbol) {
|
||||
static constexpr std::array<u8, 16> Salt = {0x51, 0x8D, 0x64, 0xA6, 0x35, 0xDE, 0xD8, 0xC1,
|
||||
0xE6, 0xB0, 0x39, 0xB1, 0xC3, 0xE5, 0x52, 0x30};
|
||||
std::vector<u8> input(symbol.size() + Salt.size());
|
||||
std::memcpy(input.data(), symbol.data(), symbol.size());
|
||||
std::memcpy(input.data() + symbol.size(), Salt.data(), Salt.size());
|
||||
|
||||
std::array<u8, CryptoPP::SHA1::DIGESTSIZE> hash;
|
||||
CryptoPP::SHA1().CalculateDigest(hash.data(), input.data(), input.size());
|
||||
|
||||
u64 digest;
|
||||
std::memcpy(&digest, hash.data(), sizeof(digest));
|
||||
|
||||
static constexpr std::string_view codes =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
|
||||
std::string dst(11, '\0');
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
dst[i] = codes[(digest >> (58 - i * 6)) & 0x3f];
|
||||
}
|
||||
dst[10] = codes[(digest & 0xf) * 4];
|
||||
return dst;
|
||||
}
|
||||
|
||||
Module::Module(Core::MemoryManager* memory_, const std::filesystem::path& file_, u32& max_tls_index)
|
||||
: memory{memory_}, file{file_}, name{file.stem().string()} {
|
||||
elf.Open(file);
|
||||
|
@ -489,4 +515,15 @@ const LibraryInfo* Module::FindLibrary(std::string_view id) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void* Module::FindByName(std::string_view name) {
|
||||
const auto nid_str = StringToNid(name);
|
||||
const auto symbols = export_sym.GetSymbols();
|
||||
const auto it = std::ranges::find_if(
|
||||
symbols, [&](const Loader::SymbolRecord& record) { return record.name.contains(nid_str); });
|
||||
if (it != symbols.end()) {
|
||||
return reinterpret_cast<void*>(it->virtual_address);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
@ -165,15 +165,6 @@ public:
|
|||
return elf.IsSharedLib();
|
||||
}
|
||||
|
||||
void* FindByName(std::string_view name) {
|
||||
const auto symbols = export_sym.GetSymbols();
|
||||
const auto it = std::ranges::find(symbols, name, &Loader::SymbolRecord::nid_name);
|
||||
if (it != symbols.end()) {
|
||||
return reinterpret_cast<void*>(it->virtual_address);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T = VAddr>
|
||||
T GetProcParam() const noexcept {
|
||||
return reinterpret_cast<T>(proc_param_virtual_addr);
|
||||
|
@ -217,6 +208,8 @@ public:
|
|||
void LoadDynamicInfo();
|
||||
void LoadSymbols();
|
||||
|
||||
void* FindByName(std::string_view name);
|
||||
|
||||
OrbisKernelModuleInfoEx GetModuleInfoEx() const;
|
||||
const ModuleInfo* FindModule(std::string_view id);
|
||||
const LibraryInfo* FindLibrary(std::string_view id);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma clang optimize off
|
||||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
#include "common/debug.h"
|
||||
|
|
Loading…
Reference in a new issue