From c6af9d87b5bd6653a9af1a09f5f68622c7633591 Mon Sep 17 00:00:00 2001 From: raziel1000 Date: Tue, 4 Jun 2024 22:41:38 -0600 Subject: [PATCH] fs: kernelOpen mode rdrw and create savedata: mount mode 9 and 34 pthread/kernel: a bunch of functions --- src/core/libraries/kernel/file_system.cpp | 6 + src/core/libraries/kernel/libkernel.cpp | 22 ++- .../libraries/kernel/memory_management.cpp | 29 +++- src/core/libraries/kernel/memory_management.h | 6 +- .../libraries/kernel/thread_management.cpp | 161 +++++++++++++++--- src/core/libraries/kernel/thread_management.h | 6 + src/core/libraries/kernel/time_management.cpp | 56 +++--- .../libraries/libc_internal/libc_internal.cpp | 5 + .../libraries/libc_internal/libc_internal.h | 1 + src/core/libraries/save_data/savedata.cpp | 4 +- 10 files changed, 228 insertions(+), 68 deletions(-) diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 1dec459d..7505fe9f 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -54,6 +54,12 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) { file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read); } else if (write && create && truncate) { file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Write); + } else if (rdwr) { + if (create) { // Create an empty file first. + Common::FS::IOFile out(file->m_host_name, Common::FS::FileAccessMode::Write); + } + // RW, then scekernelWrite is called and savedata is written just fine now. + file->f.Open(file->m_host_name, Common::FS::FileAccessMode::ReadWrite); } else { UNREACHABLE(); } diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index be92e6dc..1b93cdb8 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -7,6 +7,7 @@ #include "common/error.h" #include "common/logging/log.h" #include "common/singleton.h" +#include "core/file_sys/fs.h" #include "core/libraries/error_codes.h" #include "core/libraries/kernel/cpu_management.h" #include "core/libraries/kernel/event_flag/event_flag.h" @@ -18,7 +19,6 @@ #include "core/libraries/kernel/time_management.h" #include "core/libraries/libs.h" #include "core/linker.h" -#include "core/file_sys/fs.h" #include "core/memory.h" #ifdef _WIN64 #include @@ -54,10 +54,6 @@ int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { return SCE_OK; } -void PS4_SYSV_ABI sceKernelUsleep(u32 microseconds) { - std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); -} - struct iovec { void* iov_base; /* Base address. */ size_t iov_len; /* Length. */ @@ -221,7 +217,7 @@ s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) { strlen(std::fgets(static_cast(buf), static_cast(nbytes), stdin))); } -size_t PS4_SYSV_ABI sceKernelPread(int fd, void *buf, size_t count, uint64_t offset) { +size_t PS4_SYSV_ABI sceKernelPread(int fd, void* buf, size_t count, uint64_t offset) { long unsigned int read_bytes = 0; OVERLAPPED overlapped; @@ -236,8 +232,8 @@ size_t PS4_SYSV_ABI sceKernelPread(int fd, void *buf, size_t count, uint64_t off return file.ReadRaw(buf, count); } -s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char *moduleFileName, size_t args, const void *argp, - u32 flags, const void *pOpt, int *pRes) { +s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, size_t args, const void* argp, + u32 flags, const void* pOpt, int* pRes) { LOG_INFO(Lib_Kernel, "called filename = {}, args = {}", moduleFileName, args); if (flags != 0) { @@ -261,7 +257,7 @@ s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char *moduleFileName, size_t arg return handle; } -s32 PS4_SYSV_ABI sceKernelDlsym(s32 handle, const char *symbol, void **addrp) { +s32 PS4_SYSV_ABI sceKernelDlsym(s32 handle, const char* symbol, void** addrp) { auto* linker = Common::Singleton::Instance(); auto* module = linker->GetModule(handle); *addrp = module->FindByName(symbol); @@ -279,16 +275,19 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("B+vc2AO2Zrc", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateMainDirectMemory); LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize); + LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory); LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory); LIB_FUNCTION("WFcfL2lzido", "libkernel", 1, "libkernel", 1, 1, sceKernelQueryMemoryProtection); LIB_FUNCTION("BHouLQzh0X0", "libkernel", 1, "libkernel", 1, 1, sceKernelDirectMemoryQuery); LIB_FUNCTION("MBuItvba6z8", "libkernel", 1, "libkernel", 1, 1, sceKernelReleaseDirectMemory); - LIB_FUNCTION("hwVSPCmp5tM", "libkernel", 1, "libkernel", 1, 1, sceKernelCheckedReleaseDirectMemory); + LIB_FUNCTION("hwVSPCmp5tM", "libkernel", 1, "libkernel", 1, 1, + sceKernelCheckedReleaseDirectMemory); LIB_FUNCTION("cQke9UuBQOk", "libkernel", 1, "libkernel", 1, 1, sceKernelMunmap); LIB_FUNCTION("mL8NDH86iQI", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedFlexibleMemory); LIB_FUNCTION("IWIBBdTHit4", "libkernel", 1, "libkernel", 1, 1, sceKernelMapFlexibleMemory); LIB_FUNCTION("rVjRvHJ0X6c", "libkernel", 1, "libkernel", 1, 1, sceKernelVirtualQuery); - LIB_FUNCTION("p5EcQeEeJAE", "libkernel", 1, "libkernel", 1, 1, _sceKernelRtldSetApplicationHeapAPI); + LIB_FUNCTION("p5EcQeEeJAE", "libkernel", 1, "libkernel", 1, 1, + _sceKernelRtldSetApplicationHeapAPI); LIB_FUNCTION("wzvqT4UqKX8", "libkernel", 1, "libkernel", 1, 1, sceKernelLoadStartModule); LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym); @@ -303,7 +302,6 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail); LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error); LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", 1, 1, posix_mmap); - LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep); LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev); LIB_FUNCTION("959qrazPIrg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcParam); LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime); diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index cb7f2077..3e6cb01d 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -7,8 +7,8 @@ #include "common/singleton.h" #include "core/libraries/error_codes.h" #include "core/libraries/kernel/memory_management.h" -#include "core/memory.h" #include "core/linker.h" +#include "core/memory.h" namespace Libraries::Kernel { @@ -60,12 +60,13 @@ s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, physAddrOut); } -int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, - s64 directMemoryStart, u64 alignment) { - LOG_INFO( - Kernel_Vmm, - "len = {:#x}, prot = {:#x}, flags = {:#x}, directMemoryStart = {:#x}, alignment = {:#x}", - len, prot, flags, directMemoryStart, alignment); +int PS4_SYSV_ABI sceKernelMapNamedDirectMemory(void** addr, u64 len, int prot, int flags, + s64 directMemoryStart, u64 alignment, + const char* name) { + LOG_INFO(Kernel_Vmm, + "len = {:#x}, prot = {:#x}, flags = {:#x}, directMemoryStart = {:#x}, alignment = " + "{:#x}, name = {}", + len, prot, flags, directMemoryStart, alignment, name); if (len == 0 || !Common::Is16KBAligned(len)) { LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 16KB aligned!"); @@ -90,6 +91,17 @@ int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int fl directMemoryStart, alignment); } +int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, + s64 directMemoryStart, u64 alignment) { + LOG_INFO(Kernel_Vmm, + "redirected to sceKernelMapNamedDirectMemory: " + "len = {:#x}, prot = {:#x}, flags = {:#x}, directMemoryStart = {:#x}, alignment = " + "{:#x}", + len, prot, flags, directMemoryStart, alignment); + return sceKernelMapNamedDirectMemory(addr, len, prot, flags, directMemoryStart, alignment, + "Turtle"); +} + s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addr_in_out, std::size_t len, int prot, int flags, const char* name) { @@ -139,7 +151,8 @@ int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInf return memory->DirectMemoryQuery(offset, flags == 1, query_info); } -s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void *addr, int flags, OrbisVirtualQueryInfo *info, size_t infoSize) { +s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtualQueryInfo* info, + size_t infoSize) { auto* memory = Core::Memory::Instance(); return memory->VirtualQuery(std::bit_cast(addr), flags, info); } diff --git a/src/core/libraries/kernel/memory_management.h b/src/core/libraries/kernel/memory_management.h index aa8cb45e..947ba441 100644 --- a/src/core/libraries/kernel/memory_management.h +++ b/src/core/libraries/kernel/memory_management.h @@ -59,6 +59,9 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u u64 alignment, int memoryType, s64* physAddrOut); s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, s64* physAddrOut); +int PS4_SYSV_ABI sceKernelMapNamedDirectMemory(void** addr, u64 len, int prot, int flags, + s64 directMemoryStart, u64 alignment, + const char* name); int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, s64 directMemoryStart, u64 alignment); s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addrInOut, std::size_t len, int prot, @@ -70,7 +73,8 @@ int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info, size_t infoSize); -s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void *addr, int flags, OrbisVirtualQueryInfo *info, size_t infoSize); +s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtualQueryInfo* info, + size_t infoSize); void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func); diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index 1faf394b..5d5737cd 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -88,7 +88,18 @@ int PS4_SYSV_ABI scePthreadAttrDestroy(ScePthreadAttr* attr) { return SCE_KERNEL_ERROR_EINVAL; } -int PS4_SYSV_ABI pthread_attr_destroy(ScePthreadAttr* attr) { +int PS4_SYSV_ABI scePthreadAttrGetstack(ScePthreadAttr* attr, void** addr, size_t* size) { + + int result = pthread_attr_getstack(&(*attr)->pth_attr, addr, size); + LOG_INFO(Kernel_Pthread, "scePthreadAttrGetstack: result = {}", result); + + if (result == 0) { + return SCE_OK; + } + return SCE_KERNEL_ERROR_EINVAL; +} + +int PS4_SYSV_ABI posix_pthread_attr_destroy(ScePthreadAttr* attr) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit"); int result = scePthreadAttrDestroy(attr); if (result < 0) { @@ -682,7 +693,52 @@ int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex* } } -int PS4_SYSV_ABI pthread_attr_init(ScePthreadAttr* attr) { +int PS4_SYSV_ABI scePthreadCondDestroy(ScePthreadCond* cond) { + if (cond == nullptr) { + return SCE_KERNEL_ERROR_EINVAL; + } + int result = pthread_cond_destroy(&(*cond)->cond); + + LOG_INFO(Kernel_Pthread, "scePthreadCondDestroy, result={}", result); + + switch (result) { + case 0: + return SCE_OK; + case EBUSY: + return SCE_KERNEL_ERROR_EBUSY; + default: + return SCE_KERNEL_ERROR_EINVAL; + } +} + +int PS4_SYSV_ABI posix_pthread_condattr_init(ScePthreadCondattr* attr) { + int result = scePthreadCondattrInit(attr); + LOG_INFO(Kernel_Pthread, "redirect to scePthreadCondattrInit: result = {}", result); + if (result < 0) { + UNREACHABLE(); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_cond_init(ScePthreadCond* cond, const ScePthreadCondattr* attr) { + int result = scePthreadCondInit(cond, attr, ""); + LOG_INFO(Kernel_Pthread, "redirect to scePthreadCondInit: result = {}", result); + if (result < 0) { + UNREACHABLE(); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_condattr_destroy(ScePthreadCondattr* attr) { + int result = scePthreadCondattrDestroy(attr); + LOG_INFO(Kernel_Pthread, "redirect to scePthreadCondattrDestroy: result = {}", result); + if (result < 0) { + UNREACHABLE(); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_attr_init(ScePthreadAttr* attr) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit"); int result = scePthreadAttrInit(attr); if (result < 0) { @@ -694,7 +750,7 @@ int PS4_SYSV_ABI pthread_attr_init(ScePthreadAttr* attr) { return result; } -int PS4_SYSV_ABI pthread_attr_setstacksize(ScePthreadAttr* attr, size_t stacksize) { +int PS4_SYSV_ABI posix_pthread_attr_setstacksize(ScePthreadAttr* attr, size_t stacksize) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit"); int result = scePthreadAttrSetstacksize(attr, stacksize); if (result < 0) { @@ -706,7 +762,7 @@ int PS4_SYSV_ABI pthread_attr_setstacksize(ScePthreadAttr* attr, size_t stacksiz return result; } -int PS4_SYSV_ABI pthread_attr_setdetachstate(ScePthreadAttr* attr, int detachstate) { +int PS4_SYSV_ABI posix_pthread_attr_setdetachstate(ScePthreadAttr* attr, int detachstate) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit"); int result = scePthreadAttrSetdetachstate(attr, detachstate); if (result < 0) { @@ -718,7 +774,7 @@ int PS4_SYSV_ABI pthread_attr_setdetachstate(ScePthreadAttr* attr, int detachsta return result; } -int PS4_SYSV_ABI pthread_mutexattr_init(ScePthreadMutexattr* attr) { +int PS4_SYSV_ABI posix_pthread_mutexattr_init(ScePthreadMutexattr* attr) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit"); int result = scePthreadMutexattrInit(attr); if (result < 0) { @@ -730,7 +786,7 @@ int PS4_SYSV_ABI pthread_mutexattr_init(ScePthreadMutexattr* attr) { return result; } -int PS4_SYSV_ABI pthread_mutexattr_settype(ScePthreadMutexattr* attr, int type) { +int PS4_SYSV_ABI posix_pthread_mutexattr_settype(ScePthreadMutexattr* attr, int type) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit"); int result = scePthreadMutexattrSettype(attr, type); if (result < 0) { @@ -742,6 +798,23 @@ int PS4_SYSV_ABI pthread_mutexattr_settype(ScePthreadMutexattr* attr, int type) return result; } +int PS4_SYSV_ABI posix_pthread_mutexattr_destroy(ScePthreadMutexattr* attr) { + int result = scePthreadMutexattrDestroy(attr); + if (result < 0) { + UNREACHABLE(); + } + return result; +} + +int PS4_SYSV_ABI posix_pthread_mutexattr_setprotocol(ScePthreadMutexattr* attr, int protocol) { + int result = scePthreadMutexattrSetprotocol(attr, protocol); + LOG_INFO(Kernel_Pthread, "redirect to scePthreadMutexattrSetprotocol: result = {}", result); + if (result < 0) { + UNREACHABLE(); + } + return result; +} + int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr) { // LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit"); int result = scePthreadMutexInit(mutex, attr, nullptr); @@ -778,6 +851,14 @@ int PS4_SYSV_ABI posix_pthread_mutex_unlock(ScePthreadMutex* mutex) { return result; } +int PS4_SYSV_ABI posix_pthread_mutex_trylock(ScePthreadMutex* mutex) { + int result = scePthreadMutexTrylock(mutex); + if (result < 0) { + UNREACHABLE(); + } + return result; +} + int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond) { LOG_INFO(Kernel_Pthread, "posix posix_pthread_cond_broadcast redirect to scePthreadCondBroadcast"); @@ -835,21 +916,26 @@ int PS4_SYSV_ABI sceKernelNanosleep(const SceKernelTimespec* rqtp, SceKernelTime if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0) { return SCE_KERNEL_ERROR_EINVAL; } - - u64 nanos = rqtp->tv_sec * 1000000000 + rqtp->tv_nsec; + auto start = std::chrono::high_resolution_clock::now(); + u64 nanos = rqtp->tv_sec * 1000000000L + rqtp->tv_nsec; std::this_thread::sleep_for(std::chrono::nanoseconds(nanos)); if (rmtp != nullptr) { - UNREACHABLE(); // not supported yet + auto end = std::chrono::high_resolution_clock::now(); + auto diff = std::chrono::duration_cast(end - start).count(); + rmtp->tv_sec = (diff / 1000000000L); + rmtp->tv_nsec = (diff % 1000000000L); } return SCE_OK; } -int PS4_SYSV_ABI nanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) { + +int PS4_SYSV_ABI posix_nanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) { int result = sceKernelNanosleep(rqtp, rmtp); if (result < 0) { UNREACHABLE(); // TODO return posix error code } return result; } + static int pthread_copy_attributes(ScePthreadAttr* dst, const ScePthreadAttr* src) { if (dst == nullptr || *dst == nullptr || src == nullptr || *src == nullptr) { return SCE_KERNEL_ERROR_EINVAL; @@ -978,8 +1064,8 @@ int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr } } -int PS4_SYSV_ABI pthread_create(ScePthread* thread, const ScePthreadAttr* attr, - pthreadEntryFunc start_routine, void* arg) { +int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr, + pthreadEntryFunc start_routine, void* arg) { LOG_INFO(Kernel_Pthread, "posix pthread_create redirect to scePthreadCreate"); int result = scePthreadCreate(thread, attr, start_routine, arg, "PS4_Thread"); if (result != 0) { @@ -1018,7 +1104,13 @@ void PS4_SYSV_ABI scePthreadYield() { } int PS4_SYSV_ABI scePthreadDetach(ScePthread thread) { - LOG_INFO(Kernel_Pthread, "thread create name = {}", thread->name); + LOG_INFO(Kernel_Pthread, "thread detach name = {}", thread->name); + thread->is_detached = true; + return ORBIS_OK; +} + +int PS4_SYSV_ABI posix_pthread_detach(ScePthread thread) { + LOG_INFO(Kernel_Pthread, "thread detach name = {}", thread->name); thread->is_detached = true; return ORBIS_OK; } @@ -1168,7 +1260,7 @@ int PS4_SYSV_ABI scePthreadRwlockInit(ScePthreadRw* thread, ScePthreadRwAttr* at } int result = pthread_rwlock_init(&(*thread)->pth_rwlock, &(*attr)->attr_rwlock); - //LOG_INFO(Kernel_Pthread, "scePthreadRwlockInit: result = {}", result); + // LOG_INFO(Kernel_Pthread, "scePthreadRwlockInit: result = {}", result); switch (result) { case 0: @@ -1253,7 +1345,7 @@ int PS4_SYSV_ABI scePthreadRwlockattrInit(ScePthreadRwAttr* attr) { *attr = new PthreadRwLockAttrInernal{}; int result = pthread_rwlockattr_init(&(*attr)->attr_rwlock); - //LOG_INFO(Kernel_Pthread, "scePthreadRwlockattrInit: result = {}", result); + // LOG_INFO(Kernel_Pthread, "scePthreadRwlockattrInit: result = {}", result); switch (result) { case 0: @@ -1282,6 +1374,10 @@ int PS4_SYSV_ABI posix_pthread_rwlock_unlock(ScePthreadRw* thread) { return result; } +int PS4_SYSV_ABI sched_get_priority_max() { + return ORBIS_KERNEL_PRIO_FIFO_HIGHEST; +} + void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy); LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate); @@ -1289,7 +1385,9 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("DzES9hQF4f4", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedparam); LIB_FUNCTION("nsYoNRywwNg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrInit); LIB_FUNCTION("62KCwEMmzcM", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrDestroy); + LIB_FUNCTION("-quPa4SEJUw", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGetstack); LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach); + LIB_FUNCTION("+U1R4WtXvoc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_detach); LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, scePthreadEqual); LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf); @@ -1323,29 +1421,44 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("waPcxYiR3WA", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrDestroy); LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal); LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait); + LIB_FUNCTION("g+PZd2hiacg", "libkernel", 1, "libkernel", 1, 1, scePthreadCondDestroy); // posix calls - LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", 1, 1, pthread_attr_init); - LIB_FUNCTION("2Q0z6rnBrTE", "libScePosix", 1, "libkernel", 1, 1, pthread_attr_setstacksize); - LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1, pthread_attr_setdetachstate); - LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, pthread_create); - LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", 1, 1, pthread_attr_destroy); + LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_init); + LIB_FUNCTION("2Q0z6rnBrTE", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_attr_setstacksize); + LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_attr_setdetachstate); + LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create); + LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_destroy); + LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init); + LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_condattr_init); + LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_condattr_destroy); - LIB_FUNCTION("dQHWEsJtoE4", "libScePosix", 1, "libkernel", 1, 1, pthread_mutexattr_init); - LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", 1, 1, pthread_mutexattr_settype); + LIB_FUNCTION("dQHWEsJtoE4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutexattr_init); + LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_mutexattr_settype); + LIB_FUNCTION("5txKfcMUAok", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_mutexattr_setprotocol); LIB_FUNCTION("ttHNfU+qDBU", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_init); LIB_FUNCTION("ltCfaGr2JGE", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_destroy); LIB_FUNCTION("7H0iTOciTLo", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_lock); LIB_FUNCTION("2Z+PpY6CaJg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock); + LIB_FUNCTION("K-jXhbt2gn4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_trylock); LIB_FUNCTION("mkx2fVhNMsg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); LIB_FUNCTION("h9CcP3J0oVM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_join); LIB_FUNCTION("pDuPEf3m4fI", "libScePosix", 1, "libkernel", 1, 1, posix_sem_init); LIB_FUNCTION("YCV5dGGBcCo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_wait); LIB_FUNCTION("IKP8typ0QUk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_post); + LIB_FUNCTION("HF7lK46xzjY", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_mutexattr_destroy); LIB_FUNCTION("QBi7HCK03hw", "libkernel", 1, "libkernel", 1, 1, sceKernelClockGettime); + LIB_FUNCTION("QvsZxomvUHs", "libkernel", 1, "libkernel", 1, 1, sceKernelNanosleep); LIB_FUNCTION("lLMT9vJAck0", "libkernel", 1, "libkernel", 1, 1, clock_gettime); LIB_FUNCTION("lLMT9vJAck0", "libScePosix", 1, "libkernel", 1, 1, clock_gettime); - LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, nanosleep); + LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, posix_nanosleep); + LIB_FUNCTION("yS8U2TGCe1A", "libkernel", 1, "libkernel", 1, 1, posix_nanosleep); // CUSA18841 // Rwlock funstions LIB_FUNCTION("6ULAa0fq4jA", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockInit); @@ -1361,6 +1474,8 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock); LIB_FUNCTION("2Z+PpY6CaJg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock); LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); + + LIB_FUNCTION("CBNtXOoef-E", "libScePosix", 1, "libkernel", 1, 1, sched_get_priority_max); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/thread_management.h b/src/core/libraries/kernel/thread_management.h index 46490377..ea022edf 100644 --- a/src/core/libraries/kernel/thread_management.h +++ b/src/core/libraries/kernel/thread_management.h @@ -44,6 +44,10 @@ struct SceKernelTimespec { int64_t tv_nsec; }; +constexpr int ORBIS_KERNEL_PRIO_FIFO_DEFAULT = 700; +constexpr int ORBIS_KERNEL_PRIO_FIFO_HIGHEST = 256; +constexpr int ORBIS_KERNEL_PRIO_FIFO_LOWEST = 767; + struct PthreadInternal { u8 reserved[4096]; std::string name; @@ -178,6 +182,7 @@ int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type) int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol); int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex); int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex); +int PS4_SYSV_ABI scePthreadMutexTrylock(ScePthreadMutex* mutex); /**** * Cond calls */ @@ -185,6 +190,7 @@ int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondat const char* name); int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr); int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond); +int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr); /**** * Posix calls */ diff --git a/src/core/libraries/kernel/time_management.cpp b/src/core/libraries/kernel/time_management.cpp index 0a1b1156..6aad85cc 100644 --- a/src/core/libraries/kernel/time_management.cpp +++ b/src/core/libraries/kernel/time_management.cpp @@ -42,71 +42,78 @@ int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval* tp) {} #define FILETIME_1970 116444736000000000ull /* seconds between 1/1/1601 and 1/1/1970 */ #define HECTONANOSEC_PER_SEC 10000000ull -int PS4_SYSV_ABI getntptimeofday(struct timespec *tp, struct timezone *z) { +int PS4_SYSV_ABI getntptimeofday(struct timespec* tp, struct timezone* z) { int res = 0; union { unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ FILETIME ft; - } _now; - TIME_ZONE_INFORMATION TimeZoneInformation; + } _now; + TIME_ZONE_INFORMATION TimeZoneInformation; DWORD tzi; - if (z != NULL) - { + if (z != NULL) { if ((tzi = GetTimeZoneInformation(&TimeZoneInformation)) != TIME_ZONE_ID_INVALID) { z->tz_minuteswest = TimeZoneInformation.Bias; if (tzi == TIME_ZONE_ID_DAYLIGHT) z->tz_dsttime = 1; else z->tz_dsttime = 0; - } - else - { + } else { z->tz_minuteswest = 0; z->tz_dsttime = 0; } } if (tp != NULL) { - typedef void (WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME); + typedef void(WINAPI * GetSystemTimeAsFileTime_t)(LPFILETIME); static GetSystemTimeAsFileTime_t GetSystemTimeAsFileTime_p /* = 0 */; /* Set function pointer during first call */ GetSystemTimeAsFileTime_t get_time = - __atomic_load_n (&GetSystemTimeAsFileTime_p, __ATOMIC_RELAXED); + __atomic_load_n(&GetSystemTimeAsFileTime_p, __ATOMIC_RELAXED); if (get_time == NULL) { /* Use GetSystemTimePreciseAsFileTime() if available (Windows 8 or later) */ - get_time = (GetSystemTimeAsFileTime_t)(intptr_t) GetProcAddress ( - GetModuleHandle ("kernel32.dll"), + get_time = (GetSystemTimeAsFileTime_t)(intptr_t)GetProcAddress( + GetModuleHandle("kernel32.dll"), "GetSystemTimePreciseAsFileTime"); /* <1us precision on Windows 10 */ if (get_time == NULL) get_time = GetSystemTimeAsFileTime; /* >15ms precision on Windows 10 */ - __atomic_store_n (&GetSystemTimeAsFileTime_p, get_time, __ATOMIC_RELAXED); + __atomic_store_n(&GetSystemTimeAsFileTime_p, get_time, __ATOMIC_RELAXED); } - get_time (&_now.ft); /* 100 nano-seconds since 1-1-1601 */ - _now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */ - tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC; /* seconds since 1-1-1970 */ - tp->tv_nsec = (long) (_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* nanoseconds */ + get_time(&_now.ft); /* 100 nano-seconds since 1-1-1601 */ + _now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */ + tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC; /* seconds since 1-1-1970 */ + tp->tv_nsec = (long)(_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* nanoseconds */ } return res; } -int PS4_SYSV_ABI gettimeofday(struct timeval *p, struct timezone *z) { +int PS4_SYSV_ABI gettimeofday(struct timeval* p, struct timezone* z) { struct timespec tp; - if (getntptimeofday (&tp, z)) + if (getntptimeofday(&tp, z)) return -1; - p->tv_sec=tp.tv_sec; - p->tv_usec=(tp.tv_nsec/1000); + p->tv_sec = tp.tv_sec; + p->tv_usec = (tp.tv_nsec / 1000); return 0; } -int PS4_SYSV_ABI usleep(u64 microseconds) { +int PS4_SYSV_ABI sceKernelUsleep(u32 microseconds) { std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); return 0; } +int PS4_SYSV_ABI posix_usleep(u32 microseconds) { + std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); + return 0; +} + +u32 PS4_SYSV_ABI sceKernelSleep(u32 seconds) { + std::this_thread::sleep_for(std::chrono::seconds(seconds)); + return 0; +} + void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) { clock = std::make_unique(); initial_ptc = clock->GetUptime(); @@ -118,7 +125,10 @@ void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("1j3S3n-tTW4", "libkernel", 1, "libkernel", 1, 1, sceKernelGetTscFrequency); LIB_FUNCTION("n88vx3C5nW8", "libScePosix", 1, "libkernel", 1, 1, gettimeofday); LIB_FUNCTION("n88vx3C5nW8", "libkernel", 1, "libkernel", 1, 1, gettimeofday); - LIB_FUNCTION("QcteRwbsnV0", "libScePosix", 1, "libkernel", 1, 1, usleep); + LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep); + LIB_FUNCTION("QcteRwbsnV0", "libScePosix", 1, "libkernel", 1, 1, posix_usleep); + LIB_FUNCTION("-ZR+hG7aDHw", "libkernel", 1, "libkernel", 1, 1, sceKernelSleep); + LIB_FUNCTION("0wu33hunNdE", "libScePosix", 1, "libkernel", 1, 1, sceKernelSleep); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/libc_internal/libc_internal.cpp b/src/core/libraries/libc_internal/libc_internal.cpp index 93c98075..1deeefa4 100644 --- a/src/core/libraries/libc_internal/libc_internal.cpp +++ b/src/core/libraries/libc_internal/libc_internal.cpp @@ -43,6 +43,10 @@ float PS4_SYSV_ABI internal_expf(float x) { return expf(x); } +double PS4_SYSV_ABI internal_pow(double base, double exponent) { + return pow(base, exponent); +} + void RegisterlibSceLibcInternal(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("NFLs+dRJGNg", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_memcpy_s); @@ -55,6 +59,7 @@ void RegisterlibSceLibcInternal(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("DfivPArhucg", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_memcmp); LIB_FUNCTION("8zsu04XNsZ4", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_expf); + LIB_FUNCTION("9LCjpWyQ5Zc", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_pow); }; } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/libc_internal/libc_internal.h b/src/core/libraries/libc_internal/libc_internal.h index 819c15b4..67d01e55 100644 --- a/src/core/libraries/libc_internal/libc_internal.h +++ b/src/core/libraries/libc_internal/libc_internal.h @@ -16,6 +16,7 @@ int PS4_SYSV_ABI internal_memcpy_s(void* dest, size_t destsz, const void* src, s int PS4_SYSV_ABI internal_strcpy_s(char* dest, size_t dest_size, const char* src); int PS4_SYSV_ABI internal_memcmp(const void* s1, const void* s2, size_t n); float PS4_SYSV_ABI internal_expf(float x); +double PS4_SYSV_ABI internal_pow(double base, double exponent); void RegisterlibSceLibcInternal(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index d3e585c0..5e1ac48f 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -340,7 +340,8 @@ s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode, std::to_string(user_id) / "savedata" / id / dir_name; switch (mount_mode) { case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY: - case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: { + case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: + case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY | ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF: { if (!std::filesystem::exists(mount_dir)) { return ORBIS_SAVE_DATA_ERROR_NOT_FOUND; } @@ -364,6 +365,7 @@ s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode, mount_result->mount_status = 1; strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16); } break; + case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR | ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: { if (!std::filesystem::exists(mount_dir)) {