mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-25 20:25:38 -06:00
Libcinternal threads
fopen stores a valid pthread mutex in the FILE struct. Since this is exposed to the game/app, we need to handle this accurately.
This commit is contained in:
parent
cc3d92e675
commit
ebd62b525d
@ -494,6 +494,8 @@ set(HLE_LIBC_INTERNAL_LIB src/core/libraries/libc_internal/libc_internal.cpp
|
||||
src/core/libraries/libc_internal/libc_internal_str.h
|
||||
src/core/libraries/libc_internal/libc_internal_math.cpp
|
||||
src/core/libraries/libc_internal/libc_internal_math.h
|
||||
src/core/libraries/libc_internal/libc_internal_threads.cpp
|
||||
src/core/libraries/libc_internal/libc_internal_threads.h
|
||||
src/core/libraries/libc_internal/printf.h
|
||||
)
|
||||
|
||||
|
||||
@ -28,6 +28,16 @@ int PS4_SYSV_ABI posix_pthread_create(PthreadT* thread, const PthreadAttrT* attr
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_join(PthreadT pthread, void** thread_return);
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_init(PthreadMutexAttrT* attr);
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_settype(PthreadMutexAttrT* attr, PthreadMutexType type);
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_destroy(PthreadMutexAttrT* attr);
|
||||
|
||||
int PS4_SYSV_ABI scePthreadMutexInit(PthreadMutexT* mutex, const PthreadMutexAttrT* mutex_attr,
|
||||
const char* name);
|
||||
int PS4_SYSV_ABI posix_pthread_mutex_lock(PthreadMutexT* mutex);
|
||||
int PS4_SYSV_ABI posix_pthread_mutex_unlock(PthreadMutexT* mutex);
|
||||
int PS4_SYSV_ABI posix_pthread_mutex_destroy(PthreadMutexT* mutex);
|
||||
|
||||
void RegisterThreads(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
class Thread {
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "libc_internal_math.h"
|
||||
#include "libc_internal_memory.h"
|
||||
#include "libc_internal_str.h"
|
||||
#include "libc_internal_threads.h"
|
||||
#include "printf.h"
|
||||
|
||||
namespace Libraries::LibcInternal {
|
||||
@ -20,6 +21,7 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
||||
RegisterlibSceLibcInternalStr(sym);
|
||||
RegisterlibSceLibcInternalMemory(sym);
|
||||
RegisterlibSceLibcInternalIo(sym);
|
||||
RegisterlibSceLibcInternalThreads(sym);
|
||||
}
|
||||
|
||||
void ForceRegisterLib(Core::Loader::SymbolsResolver* sym) {
|
||||
|
||||
@ -11,21 +11,18 @@
|
||||
#include "core/libraries/kernel/file_system.h"
|
||||
#include "core/libraries/kernel/kernel.h"
|
||||
#include "core/libraries/kernel/posix_error.h"
|
||||
#include "core/libraries/kernel/threads.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "libc_internal_io.h"
|
||||
#include "printf.h"
|
||||
|
||||
namespace Libraries::LibcInternal {
|
||||
|
||||
s32 PS4_SYSV_ABI internal_snprintf(char* s, size_t n, VA_ARGS) {
|
||||
s32 PS4_SYSV_ABI internal_snprintf(char* s, u64 n, VA_ARGS) {
|
||||
VA_CTX(ctx);
|
||||
return snprintf_ctx(s, n, &ctx);
|
||||
}
|
||||
|
||||
void RegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("eLdDw6l0-bU", "libSceLibcInternal", 1, "libSceLibcInternal", internal_snprintf);
|
||||
}
|
||||
|
||||
std::vector<OrbisFILE*> g_files{};
|
||||
// Constants for tracking accurate file indexes.
|
||||
// Since the file struct is exposed to the application, accuracy is important.
|
||||
@ -88,7 +85,14 @@ s32 PS4_SYSV_ABI internal_fclose(OrbisFILE* stream) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("eLdDw6l0-bU", "libSceLibcInternal", 1, "libSceLibcInternal", internal_snprintf);
|
||||
LIB_FUNCTION("xGT4Mc55ViQ", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Fofind);
|
||||
LIB_FUNCTION("dREVnZkAKRE", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Foprep);
|
||||
}
|
||||
|
||||
void ForceRegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) {
|
||||
// Goal is to be minimally intrusive here to allow LLE for printf/stdout writes.
|
||||
LIB_FUNCTION("xeYO4u7uyJ0", "libSceLibcInternal", 1, "libSceLibcInternal", internal_fopen);
|
||||
LIB_FUNCTION("rQFVBXp-Cxg", "libSceLibcInternal", 1, "libSceLibcInternal", internal_fseek);
|
||||
LIB_FUNCTION("lbB+UlZqVG0", "libSceLibcInternal", 1, "libSceLibcInternal", internal_fread);
|
||||
|
||||
@ -39,18 +39,16 @@ struct OrbisFILE {
|
||||
u16 _Mode;
|
||||
u8 _Idx;
|
||||
s32 _Handle;
|
||||
|
||||
u8 *_Buf, *_Bend, *_Next;
|
||||
u8 *_Rend, *_Wend, *_Rback;
|
||||
|
||||
u16 *_WRback, _WBack[2];
|
||||
u16 unk1;
|
||||
u8 *_Rsave, *_WRend, *_WWend;
|
||||
|
||||
Orbis_Mbstatet _Wstate;
|
||||
u8* _Tmpnam;
|
||||
u8 _Back[6], _Cbuf;
|
||||
u8 unk2;
|
||||
void* _Mutex;
|
||||
|
||||
u8* _p;
|
||||
s32 _r;
|
||||
s32 _w;
|
||||
@ -58,25 +56,19 @@ struct OrbisFILE {
|
||||
s16 _file;
|
||||
Orbis__sbuf _bf;
|
||||
s32 _lbfsize;
|
||||
|
||||
void* _cookie;
|
||||
s32 PS4_SYSV_ABI (*_close)(void*);
|
||||
s32 PS4_SYSV_ABI (*_read)(void*, char*, s32);
|
||||
Orbisfpos_t PS4_SYSV_ABI (*_seek)(void*, Orbisfpos_t, s32);
|
||||
s32 (*_write)(void*, const char*, s32);
|
||||
|
||||
Orbis__sbuf _ub;
|
||||
u8* _up;
|
||||
s32 _ur;
|
||||
|
||||
u8 _ubuf[3];
|
||||
u8 _nbuf[1];
|
||||
|
||||
Orbis__sbuf _lb;
|
||||
|
||||
s32 _blksize;
|
||||
Orbisfpos_t _offset;
|
||||
|
||||
void* _fl_mutex;
|
||||
void* _fl_owner;
|
||||
s32 _fl_count;
|
||||
@ -84,6 +76,15 @@ struct OrbisFILE {
|
||||
Orbis__mbstate_t _mbstate;
|
||||
};
|
||||
|
||||
s32 PS4_SYSV_ABI internal_snprintf(char* s, u64 n, VA_ARGS);
|
||||
OrbisFILE* PS4_SYSV_ABI internal__Fofind();
|
||||
OrbisFILE* PS4_SYSV_ABI internal__Foprep(const char* path, const char* mode, OrbisFILE* file,
|
||||
s32 fd, s32 flag1, s32 flag2);
|
||||
OrbisFILE* PS4_SYSV_ABI internal_fopen(const char* path, const char* mode);
|
||||
s32 PS4_SYSV_ABI internal_fseek(OrbisFILE* stream, s64 offset, s32 whence);
|
||||
u64 PS4_SYSV_ABI internal_fread(void* ptr, u64 size, u64 nmemb, OrbisFILE* stream);
|
||||
s32 PS4_SYSV_ABI internal_fclose(OrbisFILE* stream);
|
||||
|
||||
void RegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym);
|
||||
void ForceRegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::LibcInternal
|
||||
64
src/core/libraries/libc_internal/libc_internal_threads.cpp
Normal file
64
src/core/libraries/libc_internal/libc_internal_threads.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/libraries/kernel/threads.h"
|
||||
#include "core/libraries/libc_internal/libc_internal_threads.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
||||
namespace Libraries::LibcInternal {
|
||||
|
||||
void getMutexName(char* buf, u64 size, const char* name) {
|
||||
if (name != nullptr) {
|
||||
std::snprintf(buf, size, "SceLibcI_%s", name);
|
||||
}
|
||||
std::snprintf(buf, size, "SceLibcI");
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI internal__Mtxinit(Libraries::Kernel::PthreadMutexT* mtx, const char* name) {
|
||||
char mtx_name[0x20];
|
||||
getMutexName(mtx_name, sizeof(mtx_name), name);
|
||||
|
||||
Libraries::Kernel::PthreadMutexAttrT attr{};
|
||||
s32 result = Libraries::Kernel::posix_pthread_mutexattr_init(&attr);
|
||||
if (result != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
result = Libraries::Kernel::posix_pthread_mutexattr_settype(
|
||||
&attr, Libraries::Kernel::PthreadMutexType::Recursive);
|
||||
if (result != 0) {
|
||||
s32 mtx_init_result = Libraries::Kernel::scePthreadMutexInit(mtx, &attr, mtx_name);
|
||||
result = Libraries::Kernel::posix_pthread_mutexattr_destroy(&attr);
|
||||
if (mtx_init_result == 0 && result == 0) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
Libraries::Kernel::posix_pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI internal__Mtxlock(Libraries::Kernel::PthreadMutexT* mtx) {
|
||||
s32 result = Libraries::Kernel::posix_pthread_mutex_lock(mtx);
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI internal__Mtxunlock(Libraries::Kernel::PthreadMutexT* mtx) {
|
||||
s32 result = Libraries::Kernel::posix_pthread_mutex_unlock(mtx);
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI internal__Mtxdst(Libraries::Kernel::PthreadMutexT* mtx) {
|
||||
s32 result = Libraries::Kernel::posix_pthread_mutex_destroy(mtx);
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
void RegisterlibSceLibcInternalThreads(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("z7STeF6abuU", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Mtxinit);
|
||||
LIB_FUNCTION("pE4Ot3CffW0", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Mtxlock);
|
||||
LIB_FUNCTION("cMwgSSmpE5o", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Mtxunlock);
|
||||
LIB_FUNCTION("LaPaA6mYA38", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Mtxdst);
|
||||
}
|
||||
|
||||
} // namespace Libraries::LibcInternal
|
||||
16
src/core/libraries/libc_internal/libc_internal_threads.h
Normal file
16
src/core/libraries/libc_internal/libc_internal_threads.h
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::LibcInternal {
|
||||
|
||||
void RegisterlibSceLibcInternalThreads(Core::Loader::SymbolsResolver* sym);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user