commit
67f6d8b2e4
|
@ -175,6 +175,8 @@ set(LIBC_SOURCES src/core/libraries/libc/libc.cpp
|
||||||
src/core/libraries/libc/libc_string.h
|
src/core/libraries/libc/libc_string.h
|
||||||
src/core/libraries/libc/libc_stdlib.cpp
|
src/core/libraries/libc/libc_stdlib.cpp
|
||||||
src/core/libraries/libc/libc_stdlib.h
|
src/core/libraries/libc/libc_stdlib.h
|
||||||
|
src/core/libraries/libc_internal/libc_internal.cpp
|
||||||
|
src/core/libraries/libc_internal/libc_internal.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PAD_LIB src/core/libraries/pad/pad.cpp
|
set(PAD_LIB src/core/libraries/pad/pad.cpp
|
||||||
|
|
|
@ -100,6 +100,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||||
SUB(Lib, NpScore) \
|
SUB(Lib, NpScore) \
|
||||||
SUB(Lib, NpTrophy) \
|
SUB(Lib, NpTrophy) \
|
||||||
SUB(Lib, Screenshot) \
|
SUB(Lib, Screenshot) \
|
||||||
|
SUB(Lib, LibCInternal) \
|
||||||
CLS(Frontend) \
|
CLS(Frontend) \
|
||||||
CLS(Render) \
|
CLS(Render) \
|
||||||
SUB(Render, Vulkan) \
|
SUB(Render, Vulkan) \
|
||||||
|
|
|
@ -67,6 +67,7 @@ enum class Class : u8 {
|
||||||
Lib_NpScore, ///< The LibSceNpScore implementation
|
Lib_NpScore, ///< The LibSceNpScore implementation
|
||||||
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
|
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
|
||||||
Lib_Screenshot, ///< The LibSceScreenshot implementation
|
Lib_Screenshot, ///< The LibSceScreenshot implementation
|
||||||
|
Lib_LibCInternal, ///< The LibCInternal implementation.
|
||||||
Frontend, ///< Emulator UI
|
Frontend, ///< Emulator UI
|
||||||
Render, ///< Video Core
|
Render, ///< Video Core
|
||||||
Render_Vulkan, ///< Vulkan backend
|
Render_Vulkan, ///< Vulkan backend
|
||||||
|
|
|
@ -36,6 +36,7 @@ static auto UserPaths = [] {
|
||||||
create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR);
|
create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR);
|
||||||
create_path(PathType::ShaderDir, user_dir / SHADER_DIR);
|
create_path(PathType::ShaderDir, user_dir / SHADER_DIR);
|
||||||
create_path(PathType::SaveDataDir, user_dir / SAVEDATA_DIR);
|
create_path(PathType::SaveDataDir, user_dir / SAVEDATA_DIR);
|
||||||
|
create_path(PathType::SysModuleDir, user_dir / SYSMODULES_DIR);
|
||||||
|
|
||||||
return paths;
|
return paths;
|
||||||
}();
|
}();
|
||||||
|
|
|
@ -14,6 +14,7 @@ enum class PathType {
|
||||||
ScreenshotsDir, // Where screenshots are stored.
|
ScreenshotsDir, // Where screenshots are stored.
|
||||||
ShaderDir, // Where shaders are stored.
|
ShaderDir, // Where shaders are stored.
|
||||||
SaveDataDir, // Where guest save data is stored.
|
SaveDataDir, // Where guest save data is stored.
|
||||||
|
SysModuleDir, // Where system modules are stored.
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto PORTABLE_DIR = "user";
|
constexpr auto PORTABLE_DIR = "user";
|
||||||
|
@ -23,6 +24,7 @@ constexpr auto LOG_DIR = "log";
|
||||||
constexpr auto SCREENSHOTS_DIR = "screenshots";
|
constexpr auto SCREENSHOTS_DIR = "screenshots";
|
||||||
constexpr auto SHADER_DIR = "shader";
|
constexpr auto SHADER_DIR = "shader";
|
||||||
constexpr auto SAVEDATA_DIR = "savedata";
|
constexpr auto SAVEDATA_DIR = "savedata";
|
||||||
|
constexpr auto SYSMODULES_DIR = "sys_modules";
|
||||||
|
|
||||||
// Filenames
|
// Filenames
|
||||||
constexpr auto LOG_FILE = "shad_log.txt";
|
constexpr auto LOG_FILE = "shad_log.txt";
|
||||||
|
|
|
@ -899,6 +899,94 @@ int PS4_SYSV_ABI scePthreadDetach(ScePthread thread) {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScePthread PS4_SYSV_ABI pthread_self() {
|
||||||
|
return g_pthread_self;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) {
|
||||||
|
if (cond == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = pthread_cond_signal(&(*cond)->cond);
|
||||||
|
|
||||||
|
LOG_INFO(Kernel_Pthread, "scePthreadCondSignal, 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 scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex) {
|
||||||
|
if (cond == nullptr || *cond == nullptr) {
|
||||||
|
// return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
cond = static_cast<ScePthreadCond*>(createCond(cond)); // check this. Kero Blaster.
|
||||||
|
}
|
||||||
|
if (mutex == nullptr || *mutex == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
int result = pthread_cond_wait(&(*cond)->cond, &(*mutex)->pth_mutex);
|
||||||
|
|
||||||
|
LOG_INFO(Kernel_Pthread, "scePthreadCondWait, result={}", result);
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case 0:
|
||||||
|
return SCE_OK;
|
||||||
|
case EINTR:
|
||||||
|
return SCE_KERNEL_ERROR_EINTR;
|
||||||
|
case EAGAIN:
|
||||||
|
return SCE_KERNEL_ERROR_EAGAIN;
|
||||||
|
default:
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr) {
|
||||||
|
if (attr == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
int result = pthread_condattr_destroy(&(*attr)->cond_attr);
|
||||||
|
|
||||||
|
LOG_INFO(Kernel_Pthread, "scePthreadCondattrDestroy: result = {} ", result);
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case 0:
|
||||||
|
return SCE_OK;
|
||||||
|
case ENOMEM:
|
||||||
|
return SCE_KERNEL_ERROR_ENOMEM;
|
||||||
|
default:
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI scePthreadMutexTrylock(ScePthreadMutex* mutex) {
|
||||||
|
|
||||||
|
if (mutex == nullptr) {
|
||||||
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = pthread_mutex_trylock(&(*mutex)->pth_mutex);
|
||||||
|
if (result != 0) {
|
||||||
|
LOG_INFO(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
||||||
|
}
|
||||||
|
switch (result) {
|
||||||
|
case 0:
|
||||||
|
return ORBIS_OK;
|
||||||
|
case EAGAIN:
|
||||||
|
return ORBIS_KERNEL_ERROR_EAGAIN;
|
||||||
|
case EBUSY:
|
||||||
|
return ORBIS_KERNEL_ERROR_EBUSY;
|
||||||
|
case EINVAL:
|
||||||
|
default:
|
||||||
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
|
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
|
||||||
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate);
|
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate);
|
||||||
|
@ -909,6 +997,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach);
|
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach);
|
||||||
|
|
||||||
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
|
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
|
||||||
|
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, pthread_self);
|
||||||
LIB_FUNCTION("3qxgM4ezETA", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetaffinity);
|
LIB_FUNCTION("3qxgM4ezETA", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetaffinity);
|
||||||
LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGetaffinity);
|
LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGetaffinity);
|
||||||
LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGet);
|
LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGet);
|
||||||
|
@ -927,10 +1016,14 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("1FGvU0i9saQ", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexattrSetprotocol);
|
LIB_FUNCTION("1FGvU0i9saQ", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexattrSetprotocol);
|
||||||
LIB_FUNCTION("9UK1vLZQft4", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexLock);
|
LIB_FUNCTION("9UK1vLZQft4", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexLock);
|
||||||
LIB_FUNCTION("tn3VlD0hG60", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexUnlock);
|
LIB_FUNCTION("tn3VlD0hG60", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexUnlock);
|
||||||
|
LIB_FUNCTION("upoVrzMHFeE", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexTrylock);
|
||||||
// cond calls
|
// cond calls
|
||||||
LIB_FUNCTION("2Tb92quprl0", "libkernel", 1, "libkernel", 1, 1, scePthreadCondInit);
|
LIB_FUNCTION("2Tb92quprl0", "libkernel", 1, "libkernel", 1, 1, scePthreadCondInit);
|
||||||
LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrInit);
|
LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrInit);
|
||||||
LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", 1, 1, scePthreadCondBroadcast);
|
LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", 1, 1, scePthreadCondBroadcast);
|
||||||
|
LIB_FUNCTION("WKAXJ4XBPQ4", "libkernel", 1, "libkernel", 1, 1, scePthreadCondWait);
|
||||||
|
LIB_FUNCTION("waPcxYiR3WA", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrDestroy);
|
||||||
|
LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal);
|
||||||
// posix calls
|
// posix calls
|
||||||
LIB_FUNCTION("ttHNfU+qDBU", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_init);
|
LIB_FUNCTION("ttHNfU+qDBU", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_init);
|
||||||
LIB_FUNCTION("7H0iTOciTLo", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
|
LIB_FUNCTION("7H0iTOciTLo", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
#include "core/libraries/libs.h"
|
||||||
|
#include "libc_internal.h"
|
||||||
|
|
||||||
|
namespace Libraries::LibcInternal {
|
||||||
|
|
||||||
|
void* PS4_SYSV_ABI internal_memset(void* s, int c, size_t n) {
|
||||||
|
return std::memset(s, c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* PS4_SYSV_ABI internal_memcpy(void* dest, const void* src, size_t n) {
|
||||||
|
return std::memcpy(dest, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI internal_memcpy_s(void* dest, rsize_t destsz, const void* src, rsize_t count) {
|
||||||
|
#ifdef _WIN64
|
||||||
|
return memcpy_s(dest, destsz, src, count);
|
||||||
|
#else
|
||||||
|
std::memcpy(dest, src, count);
|
||||||
|
return 0; // ALL OK
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI internal_strcpy_s(char* dest, rsize_t dest_size, const char* src) {
|
||||||
|
#ifdef _WIN64
|
||||||
|
return strcpy_s(dest, dest_size, src);
|
||||||
|
#else
|
||||||
|
std::strcpy(dest, src);
|
||||||
|
return 0; // ALL OK
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI internal_memcmp(const void* s1, const void* s2, size_t n) {
|
||||||
|
return std::memcmp(s1, s2, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
float PS4_SYSV_ABI internal_expf(float x) {
|
||||||
|
return expf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterlibSceLibcInternal(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
LIB_FUNCTION("NFLs+dRJGNg", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1,
|
||||||
|
internal_memcpy_s);
|
||||||
|
LIB_FUNCTION("Q3VBxCXhUHs", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1,
|
||||||
|
internal_memcpy);
|
||||||
|
LIB_FUNCTION("8zTFvBIAIN8", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1,
|
||||||
|
internal_memset);
|
||||||
|
LIB_FUNCTION("5Xa2ACNECdo", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1,
|
||||||
|
internal_strcpy_s);
|
||||||
|
LIB_FUNCTION("DfivPArhucg", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1,
|
||||||
|
internal_memcmp);
|
||||||
|
LIB_FUNCTION("8zsu04XNsZ4", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_expf);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::LibcInternal
|
|
@ -0,0 +1,21 @@
|
||||||
|
// 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::LibcInternal {
|
||||||
|
void* PS4_SYSV_ABI internal_memset(void* s, int c, size_t n);
|
||||||
|
void* PS4_SYSV_ABI internal_memcpy(void* dest, const void* src, size_t n);
|
||||||
|
int PS4_SYSV_ABI internal_memcpy_s(void* dest, rsize_t destsz, const void* src, rsize_t count);
|
||||||
|
int PS4_SYSV_ABI internal_strcpy_s(char* dest, rsize_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);
|
||||||
|
|
||||||
|
void RegisterlibSceLibcInternal(Core::Loader::SymbolsResolver* sym);
|
||||||
|
} // namespace Libraries::LibcInternal
|
|
@ -7,6 +7,7 @@
|
||||||
#include "core/libraries/gnmdriver/gnmdriver.h"
|
#include "core/libraries/gnmdriver/gnmdriver.h"
|
||||||
#include "core/libraries/kernel/libkernel.h"
|
#include "core/libraries/kernel/libkernel.h"
|
||||||
#include "core/libraries/libc/libc.h"
|
#include "core/libraries/libc/libc.h"
|
||||||
|
#include "core/libraries/libc_internal/libc_internal.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "core/libraries/network/http.h"
|
#include "core/libraries/network/http.h"
|
||||||
#include "core/libraries/network/net.h"
|
#include "core/libraries/network/net.h"
|
||||||
|
@ -57,6 +58,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
||||||
Libraries::NpScore::RegisterlibSceNpScore(sym);
|
Libraries::NpScore::RegisterlibSceNpScore(sym);
|
||||||
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
|
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
|
||||||
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
|
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
|
||||||
|
Libraries::LibcInternal::RegisterlibSceLibcInternal(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries
|
} // namespace Libraries
|
||||||
|
|
|
@ -70,6 +70,14 @@ int main(int argc, char* argv[]) {
|
||||||
Libraries::InitHLELibs(&linker->getHLESymbols());
|
Libraries::InitHLELibs(&linker->getHLESymbols());
|
||||||
linker->LoadModule(path);
|
linker->LoadModule(path);
|
||||||
|
|
||||||
|
// check if we have system modules to load
|
||||||
|
const auto& sys_module_path = Common::FS::GetUserPath(Common::FS::PathType::SysModuleDir);
|
||||||
|
for (const auto& entry : std::filesystem::directory_iterator(sys_module_path)) {
|
||||||
|
if (entry.path().filename() == "libSceNgs2.sprx") {
|
||||||
|
LOG_INFO(Loader, "Loading {}", entry.path().string().c_str());
|
||||||
|
linker->LoadModule(entry.path().string().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
// Check if there is a libc.prx in sce_module folder
|
// Check if there is a libc.prx in sce_module folder
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if (Config::isLleLibc()) {
|
if (Config::isLleLibc()) {
|
||||||
|
|
Loading…
Reference in New Issue