kernel: Add basic exceptions for linux

This commit is contained in:
IndecisiveTurtle 2024-10-24 21:55:40 +03:00 committed by IndecisiveTurtle
parent ef3341c78c
commit cef37be33d
20 changed files with 351 additions and 38 deletions

View file

@ -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

View file

@ -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() {

View file

@ -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();

View file

@ -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);

View file

@ -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;

View file

@ -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);

View 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

View 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

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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);

View file

@ -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) \

View file

@ -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();
}

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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"