linker: Reduce code nesting
This commit is contained in:
parent
4087a73145
commit
772891bfa7
|
@ -102,14 +102,14 @@ struct AddressSpace::Impl {
|
||||||
|
|
||||||
// Perform the map.
|
// Perform the map.
|
||||||
void* ptr = nullptr;
|
void* ptr = nullptr;
|
||||||
if (phys_addr) {
|
if (phys_addr != -1) {
|
||||||
ptr = MapViewOfFile3(backing_handle, process, reinterpret_cast<PVOID>(virtual_addr),
|
ptr = MapViewOfFile3(backing_handle, process, reinterpret_cast<PVOID>(virtual_addr),
|
||||||
phys_addr, size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
phys_addr, size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||||
} else {
|
} else {
|
||||||
ptr = VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), size,
|
ptr = VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), size,
|
||||||
MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||||
}
|
}
|
||||||
ASSERT(ptr);
|
ASSERT_MSG(ptr, "{}", Common::GetLastErrorMsg());
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
* If zero is provided the mapping is considered as private.
|
* If zero is provided the mapping is considered as private.
|
||||||
* @return A pointer to the mapped memory.
|
* @return A pointer to the mapped memory.
|
||||||
*/
|
*/
|
||||||
void* Map(VAddr virtual_addr, size_t size, u64 alignment = 0, PAddr phys_addr = 0);
|
void* Map(VAddr virtual_addr, size_t size, u64 alignment = 0, PAddr phys_addr = -1);
|
||||||
|
|
||||||
/// Unmaps specified virtual memory area.
|
/// Unmaps specified virtual memory area.
|
||||||
void Unmap(VAddr virtual_addr, size_t size);
|
void Unmap(VAddr virtual_addr, size_t size);
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <fmt/core.h>
|
||||||
|
#include "common/assert.h"
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
|
|
||||||
namespace Core::FileSys {
|
namespace Core::FileSys {
|
||||||
|
@ -51,9 +53,11 @@ std::string MntPoints::GetHostFile(const std::string& guest_file) {
|
||||||
if (find == 0) {
|
if (find == 0) {
|
||||||
std::string npath = guest_file.substr(pair.guest_path.size(), guest_file.size() - 1);
|
std::string npath = guest_file.substr(pair.guest_path.size(), guest_file.size() - 1);
|
||||||
std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/');
|
std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/');
|
||||||
|
fmt::print("GetHostFile: {}\n", pair.host_path + npath);
|
||||||
return pair.host_path + npath;
|
return pair.host_path + npath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UNREACHABLE();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,12 +197,23 @@ int PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) {
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_stat(const char* path, OrbisKernelStat* sb) {
|
int PS4_SYSV_ABI posix_stat(const char* path, OrbisKernelStat* sb) {
|
||||||
int result = sceKernelStat(path, sb);
|
int result = sceKernelStat(path, sb);
|
||||||
|
return result;
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
UNREACHABLE(); // TODO
|
UNREACHABLE(); // TODO
|
||||||
}
|
}
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelCheckReachability(const char *path) {
|
||||||
|
LOG_INFO(Lib_Kernel, "path = {}", path);
|
||||||
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
|
std::string path_name = mnt->GetHostFile(path);
|
||||||
|
if (!std::filesystem::exists(path_name)) {
|
||||||
|
return SCE_KERNEL_ERROR_ENOENT;
|
||||||
|
}
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
||||||
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
||||||
|
@ -215,6 +226,8 @@ void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("Cg4srZ6TKbU", "libkernel", 1, "libkernel", 1, 1, sceKernelRead);
|
LIB_FUNCTION("Cg4srZ6TKbU", "libkernel", 1, "libkernel", 1, 1, sceKernelRead);
|
||||||
LIB_FUNCTION("1-LFLmRFxxM", "libkernel", 1, "libkernel", 1, 1, sceKernelMkdir);
|
LIB_FUNCTION("1-LFLmRFxxM", "libkernel", 1, "libkernel", 1, 1, sceKernelMkdir);
|
||||||
LIB_FUNCTION("eV9wAD2riIA", "libkernel", 1, "libkernel", 1, 1, sceKernelStat);
|
LIB_FUNCTION("eV9wAD2riIA", "libkernel", 1, "libkernel", 1, 1, sceKernelStat);
|
||||||
|
LIB_FUNCTION("uWyW3v98sU4", "libkernel", 1, "libkernel", 1, 1, sceKernelCheckReachability);
|
||||||
|
|
||||||
LIB_FUNCTION("E6ao34wPw+U", "libScePosix", 1, "libkernel", 1, 1, posix_stat);
|
LIB_FUNCTION("E6ao34wPw+U", "libScePosix", 1, "libkernel", 1, 1, posix_stat);
|
||||||
|
|
||||||
// openOrbis (to check if it is valid out of OpenOrbis
|
// openOrbis (to check if it is valid out of OpenOrbis
|
||||||
|
|
|
@ -204,6 +204,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
||||||
// memory
|
// memory
|
||||||
LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateDirectMemory);
|
LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateDirectMemory);
|
||||||
|
LIB_FUNCTION("B+vc2AO2Zrc", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateMainDirectMemory);
|
||||||
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
|
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
|
||||||
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
||||||
LIB_FUNCTION("WFcfL2lzido", "libkernel", 1, "libkernel", 1, 1, sceKernelQueryMemoryProtection);
|
LIB_FUNCTION("WFcfL2lzido", "libkernel", 1, "libkernel", 1, 1, sceKernelQueryMemoryProtection);
|
||||||
|
|
|
@ -22,7 +22,7 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u
|
||||||
LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!");
|
LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!");
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
const bool is_in_range = (searchStart < len && searchEnd > len);
|
const bool is_in_range = searchEnd - searchStart >= len;
|
||||||
if (len <= 0 || !Common::is16KBAligned(len) || !is_in_range) {
|
if (len <= 0 || !Common::is16KBAligned(len) || !is_in_range) {
|
||||||
LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!");
|
LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!");
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
@ -48,6 +48,10 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u
|
||||||
return SCE_OK;
|
return SCE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, s64 *physAddrOut) {
|
||||||
|
return sceKernelAllocateDirectMemory(0, SCE_KERNEL_MAIN_DMEM_SIZE, len, alignment, memoryType, physAddrOut);
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags,
|
int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags,
|
||||||
s64 directMemoryStart, u64 alignment) {
|
s64 directMemoryStart, u64 alignment) {
|
||||||
LOG_INFO(
|
LOG_INFO(
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct OrbisQueryInfo {
|
||||||
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize();
|
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize();
|
||||||
int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len,
|
int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len,
|
||||||
u64 alignment, int memoryType, s64* physAddrOut);
|
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 sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags,
|
int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags,
|
||||||
s64 directMemoryStart, u64 alignment);
|
s64 directMemoryStart, u64 alignment);
|
||||||
s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addrInOut, std::size_t len, int prot,
|
s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addrInOut, std::size_t len, int prot,
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/kernel/thread_management.h"
|
#include "core/libraries/kernel/thread_management.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
#include "core/tls.h"
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,6 +83,18 @@ int PS4_SYSV_ABI scePthreadAttrDestroy(ScePthreadAttr* attr) {
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI pthread_attr_destroy(ScePthreadAttr* attr) {
|
||||||
|
// LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit");
|
||||||
|
int result = scePthreadAttrDestroy(attr);
|
||||||
|
if (result < 0) {
|
||||||
|
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||||
|
? result + -SCE_KERNEL_ERROR_UNKNOWN
|
||||||
|
: POSIX_EOTHER;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI scePthreadAttrSetguardsize(ScePthreadAttr* attr, size_t guard_size) {
|
int PS4_SYSV_ABI scePthreadAttrSetguardsize(ScePthreadAttr* attr, size_t guard_size) {
|
||||||
if (attr == nullptr || *attr == nullptr) {
|
if (attr == nullptr || *attr == nullptr) {
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
@ -664,6 +677,66 @@ int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI pthread_attr_init(ScePthreadAttr* attr) {
|
||||||
|
// LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit");
|
||||||
|
int result = scePthreadAttrInit(attr);
|
||||||
|
if (result < 0) {
|
||||||
|
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||||
|
? result + -SCE_KERNEL_ERROR_UNKNOWN
|
||||||
|
: POSIX_EOTHER;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI 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) {
|
||||||
|
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||||
|
? result + -SCE_KERNEL_ERROR_UNKNOWN
|
||||||
|
: POSIX_EOTHER;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI 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) {
|
||||||
|
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||||
|
? result + -SCE_KERNEL_ERROR_UNKNOWN
|
||||||
|
: POSIX_EOTHER;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI pthread_mutexattr_init(ScePthreadMutexattr *attr) {
|
||||||
|
// LOG_INFO(Kernel_Pthread, "posix pthread_mutexattr_init redirect to scePthreadMutexattrInit");
|
||||||
|
int result = scePthreadMutexattrInit(attr);
|
||||||
|
if (result < 0) {
|
||||||
|
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||||
|
? result + -SCE_KERNEL_ERROR_UNKNOWN
|
||||||
|
: POSIX_EOTHER;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI 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) {
|
||||||
|
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||||
|
? result + -SCE_KERNEL_ERROR_UNKNOWN
|
||||||
|
: POSIX_EOTHER;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr) {
|
int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr) {
|
||||||
// LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit");
|
// LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit");
|
||||||
int result = scePthreadMutexInit(mutex, attr, nullptr);
|
int result = scePthreadMutexInit(mutex, attr, nullptr);
|
||||||
|
@ -829,6 +902,7 @@ static void cleanup_thread(void* arg) {
|
||||||
static void* run_thread(void* arg) {
|
static void* run_thread(void* arg) {
|
||||||
auto* thread = static_cast<ScePthread>(arg);
|
auto* thread = static_cast<ScePthread>(arg);
|
||||||
Common::SetCurrentThreadName(thread->name.c_str());
|
Common::SetCurrentThreadName(thread->name.c_str());
|
||||||
|
Core::SetTLSStorage(0, 0);
|
||||||
void* ret = nullptr;
|
void* ret = nullptr;
|
||||||
g_pthread_self = thread;
|
g_pthread_self = thread;
|
||||||
pthread_cleanup_push(cleanup_thread, thread);
|
pthread_cleanup_push(cleanup_thread, thread);
|
||||||
|
@ -898,6 +972,19 @@ 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) {
|
||||||
|
LOG_INFO(Kernel_Pthread, "posix pthread_create redirect to scePthreadCreate");
|
||||||
|
int result = scePthreadCreate(thread, attr, start_routine, arg, "PS4_Thread");
|
||||||
|
if (result != 0) {
|
||||||
|
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
|
||||||
|
? result + -SCE_KERNEL_ERROR_UNKNOWN
|
||||||
|
: POSIX_EOTHER;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ScePthread PThreadPool::Create() {
|
ScePthread PThreadPool::Create() {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
|
||||||
|
@ -1062,6 +1149,14 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal);
|
LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal);
|
||||||
LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait);
|
LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait);
|
||||||
// posix calls
|
// 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("dQHWEsJtoE4", "libScePosix", 1, "libkernel", 1, 1, pthread_mutexattr_init);
|
||||||
|
LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", 1, 1, pthread_mutexattr_settype);
|
||||||
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);
|
||||||
LIB_FUNCTION("2Z+PpY6CaJg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock);
|
LIB_FUNCTION("2Z+PpY6CaJg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock);
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
#include "common/native_clock.h"
|
#include "common/native_clock.h"
|
||||||
#include "core/libraries/kernel/time_management.h"
|
#include "core/libraries/kernel/time_management.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
static u64 initial_ptc;
|
static u64 initial_ptc;
|
||||||
|
@ -30,6 +37,57 @@ u64 PS4_SYSV_ABI sceKernelReadTsc() {
|
||||||
return clock->GetUptime();
|
return clock->GetUptime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval *tp) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
||||||
|
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
||||||
|
#else
|
||||||
|
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct timezone
|
||||||
|
{
|
||||||
|
int tz_minuteswest; /* minutes W of Greenwich */
|
||||||
|
int tz_dsttime; /* type of dst correction */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timeval {
|
||||||
|
long tv_sec;
|
||||||
|
long tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* FILETIME of Jan 1 1970 00:00:00, the PostgreSQL epoch */
|
||||||
|
static const unsigned __int64 epoch = 116444736000000000ULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FILETIME represents the number of 100-nanosecond intervals since
|
||||||
|
* January 1, 1601 (UTC).
|
||||||
|
*/
|
||||||
|
#define FILETIME_UNITS_PER_SEC 10000000L
|
||||||
|
#define FILETIME_UNITS_PER_USEC 10
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI gettimeofday(struct timeval * tp, struct timezone * tzp) {
|
||||||
|
FILETIME file_time;
|
||||||
|
ULARGE_INTEGER ularge;
|
||||||
|
|
||||||
|
GetSystemTimePreciseAsFileTime(&file_time);
|
||||||
|
ularge.LowPart = file_time.dwLowDateTime;
|
||||||
|
ularge.HighPart = file_time.dwHighDateTime;
|
||||||
|
|
||||||
|
tp->tv_sec = (long) ((ularge.QuadPart - epoch) / FILETIME_UNITS_PER_SEC);
|
||||||
|
tp->tv_usec = (long) (((ularge.QuadPart - epoch) % FILETIME_UNITS_PER_SEC)
|
||||||
|
/ FILETIME_UNITS_PER_USEC);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI usleep(u64 microseconds) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
clock = std::make_unique<Common::NativeClock>();
|
clock = std::make_unique<Common::NativeClock>();
|
||||||
initial_ptc = clock->GetUptime();
|
initial_ptc = clock->GetUptime();
|
||||||
|
@ -39,6 +97,9 @@ void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
sceKernelGetProcessTimeCounterFrequency);
|
sceKernelGetProcessTimeCounterFrequency);
|
||||||
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
|
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
|
||||||
LIB_FUNCTION("1j3S3n-tTW4", "libkernel", 1, "libkernel", 1, 1, sceKernelGetTscFrequency);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -11,11 +11,17 @@ class SymbolsResolver;
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
|
struct SceKernelTimeval {
|
||||||
|
time_t tv_sec;
|
||||||
|
s64 tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
|
u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency();
|
||||||
u64 PS4_SYSV_ABI sceKernelReadTsc();
|
u64 PS4_SYSV_ABI sceKernelReadTsc();
|
||||||
|
int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval *tp);
|
||||||
|
|
||||||
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ Module* Linker::LoadModule(const std::filesystem::path& elf_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Linker::LoadModuleToMemory(Module* m) {
|
void Linker::LoadModuleToMemory(Module* m) {
|
||||||
// get elf header, program header
|
// Retrieve elf header and program header
|
||||||
const auto elf_header = m->elf.GetElfHeader();
|
const auto elf_header = m->elf.GetElfHeader();
|
||||||
const auto elf_pheader = m->elf.GetProgramHeader();
|
const auto elf_pheader = m->elf.GetProgramHeader();
|
||||||
|
|
||||||
|
@ -383,9 +383,7 @@ const LibraryInfo* Linker::FindLibrary(const Module& m, const std::string& id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Linker::LoadSymbols(Module* m) {
|
void Linker::LoadSymbols(Module* m) {
|
||||||
|
const auto symbol_database = [this, m](Loader::SymbolsResolver* symbol, bool export_func) {
|
||||||
const auto symbol_database = [this](Module* m, Loader::SymbolsResolver* symbol,
|
|
||||||
bool export_func) {
|
|
||||||
if (m->dynamic_info.symbol_table == nullptr || m->dynamic_info.str_table == nullptr ||
|
if (m->dynamic_info.symbol_table == nullptr || m->dynamic_info.str_table == nullptr ||
|
||||||
m->dynamic_info.symbol_table_total_size == 0) {
|
m->dynamic_info.symbol_table_total_size == 0) {
|
||||||
LOG_INFO(Core_Linker, "Symbol table not found!");
|
LOG_INFO(Core_Linker, "Symbol table not found!");
|
||||||
|
@ -442,8 +440,8 @@ void Linker::LoadSymbols(Module* m) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
symbol_database(m, &m->export_sym, true);
|
symbol_database(&m->export_sym, true);
|
||||||
symbol_database(m, &m->import_sym, false);
|
symbol_database(&m->import_sym, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Linker::Relocate(Module* m) {
|
void Linker::Relocate(Module* m) {
|
||||||
|
@ -550,7 +548,6 @@ bool contains(const std::vector<T>& vecObj, const T& element) {
|
||||||
|
|
||||||
Module* Linker::FindExportedModule(const ModuleInfo& module, const LibraryInfo& library) {
|
Module* Linker::FindExportedModule(const ModuleInfo& module, const LibraryInfo& library) {
|
||||||
// std::scoped_lock lock{m_mutex};
|
// std::scoped_lock lock{m_mutex};
|
||||||
|
|
||||||
for (auto& m : m_modules) {
|
for (auto& m : m_modules) {
|
||||||
const auto& export_libs = m->dynamic_info.export_libs;
|
const auto& export_libs = m->dynamic_info.export_libs;
|
||||||
const auto& export_modules = m->dynamic_info.export_modules;
|
const auto& export_modules = m->dynamic_info.export_modules;
|
||||||
|
@ -564,56 +561,53 @@ Module* Linker::FindExportedModule(const ModuleInfo& module, const LibraryInfo&
|
||||||
|
|
||||||
void Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Module* m,
|
void Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Module* m,
|
||||||
Loader::SymbolRecord* return_info) {
|
Loader::SymbolRecord* return_info) {
|
||||||
// std::scoped_lock lock{m_mutex};
|
|
||||||
const auto ids = Common::SplitString(name, '#');
|
const auto ids = Common::SplitString(name, '#');
|
||||||
if (ids.size() == 3) {
|
if (ids.size() != 3) {
|
||||||
const auto* library = FindLibrary(*m, ids.at(1));
|
|
||||||
const auto* module = FindModule(*m, ids.at(2));
|
|
||||||
ASSERT_MSG(library && module, "Unable to find library and module");
|
|
||||||
|
|
||||||
Loader::SymbolResolver sr{};
|
|
||||||
sr.name = ids.at(0);
|
|
||||||
sr.library = library->name;
|
|
||||||
sr.library_version = library->version;
|
|
||||||
sr.module = module->name;
|
|
||||||
sr.module_version_major = module->version_major;
|
|
||||||
sr.module_version_minor = module->version_minor;
|
|
||||||
sr.type = sym_type;
|
|
||||||
|
|
||||||
const Loader::SymbolRecord* rec = nullptr;
|
|
||||||
|
|
||||||
rec = m_hle_symbols.FindSymbol(sr);
|
|
||||||
if (rec == nullptr) {
|
|
||||||
// check if it an export function
|
|
||||||
if (auto* p = FindExportedModule(*module, *library);
|
|
||||||
p != nullptr && p->export_sym.GetSize() > 0) {
|
|
||||||
rec = p->export_sym.FindSymbol(sr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rec != nullptr) {
|
|
||||||
*return_info = *rec;
|
|
||||||
} else {
|
|
||||||
auto aeronid = AeroLib::FindByNid(sr.name.c_str());
|
|
||||||
if (aeronid) {
|
|
||||||
return_info->name = aeronid->name;
|
|
||||||
return_info->virtual_address = AeroLib::GetStub(aeronid->nid);
|
|
||||||
} else {
|
|
||||||
return_info->virtual_address = AeroLib::GetStub(sr.name.c_str());
|
|
||||||
return_info->name = "Unknown !!!";
|
|
||||||
}
|
|
||||||
LOG_ERROR(Core_Linker, "Linker: Stub resolved {} as {} (lib: {}, mod: {})", sr.name,
|
|
||||||
return_info->name, library->name, module->name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return_info->virtual_address = 0;
|
return_info->virtual_address = 0;
|
||||||
return_info->name = name;
|
return_info->name = name;
|
||||||
LOG_ERROR(Core_Linker, "Not Resolved {}", name);
|
LOG_ERROR(Core_Linker, "Not Resolved {}", name);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto* library = FindLibrary(*m, ids.at(1));
|
||||||
|
const auto* module = FindModule(*m, ids.at(2));
|
||||||
|
ASSERT_MSG(library && module, "Unable to find library and module");
|
||||||
|
|
||||||
|
Loader::SymbolResolver sr{};
|
||||||
|
sr.name = ids.at(0);
|
||||||
|
sr.library = library->name;
|
||||||
|
sr.library_version = library->version;
|
||||||
|
sr.module = module->name;
|
||||||
|
sr.module_version_major = module->version_major;
|
||||||
|
sr.module_version_minor = module->version_minor;
|
||||||
|
sr.type = sym_type;
|
||||||
|
|
||||||
|
const auto* record = m_hle_symbols.FindSymbol(sr);
|
||||||
|
if (!record) {
|
||||||
|
// Check if it an export function
|
||||||
|
if (auto* p = FindExportedModule(*module, *library);
|
||||||
|
p && p->export_sym.GetSize() > 0) {
|
||||||
|
record = p->export_sym.FindSymbol(sr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (record) {
|
||||||
|
*return_info = *record;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto aeronid = AeroLib::FindByNid(sr.name.c_str());
|
||||||
|
if (aeronid) {
|
||||||
|
return_info->name = aeronid->name;
|
||||||
|
return_info->virtual_address = AeroLib::GetStub(aeronid->nid);
|
||||||
|
} else {
|
||||||
|
return_info->virtual_address = AeroLib::GetStub(sr.name.c_str());
|
||||||
|
return_info->name = "Unknown !!!";
|
||||||
|
}
|
||||||
|
LOG_ERROR(Core_Linker, "Linker: Stub resolved {} as {} (lib: {}, mod: {})", sr.name,
|
||||||
|
return_info->name, library->name, module->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 Linker::GetProcParam() {
|
u64 Linker::GetProcParam() {
|
||||||
// std::scoped_lock lock{m_mutex};
|
|
||||||
|
|
||||||
for (auto& m : m_modules) {
|
for (auto& m : m_modules) {
|
||||||
if (!m->elf.IsSharedLib()) {
|
if (!m->elf.IsSharedLib()) {
|
||||||
return m->proc_param_virtual_addr;
|
return m->proc_param_virtual_addr;
|
||||||
|
@ -621,18 +615,19 @@ u64 Linker::GetProcParam() {
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
using exit_func_t = PS4_SYSV_ABI void (*)();
|
using exit_func_t = PS4_SYSV_ABI void (*)();
|
||||||
using entry_func_t = PS4_SYSV_ABI void (*)(EntryParams* params, exit_func_t atexit_func);
|
using entry_func_t = PS4_SYSV_ABI void (*)(EntryParams* params, exit_func_t atexit_func);
|
||||||
using module_ini_func_t = PS4_SYSV_ABI int (*)(size_t args, const void* argp, module_func_t func);
|
using module_ini_func_t = PS4_SYSV_ABI int (*)(size_t args, const void* argp, ModuleFunc func);
|
||||||
|
|
||||||
static PS4_SYSV_ABI int run_module(uint64_t addr, size_t args, const void* argp,
|
static PS4_SYSV_ABI int RunModule(uint64_t addr, size_t args, const void* argp,
|
||||||
module_func_t func) {
|
ModuleFunc func) {
|
||||||
return reinterpret_cast<module_ini_func_t>(addr)(args, argp, func);
|
return reinterpret_cast<module_ini_func_t>(addr)(args, argp, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Linker::StartModule(Module* m, size_t args, const void* argp, module_func_t func) {
|
int Linker::StartModule(Module* m, size_t args, const void* argp, ModuleFunc func) {
|
||||||
LOG_INFO(Core_Linker, "Module started : {}", m->file_name);
|
LOG_INFO(Core_Linker, "Module started : {}", m->file_name);
|
||||||
return run_module(m->dynamic_info.init_virtual_addr + m->base_virtual_addr, args, argp, func);
|
return RunModule(m->dynamic_info.init_virtual_addr + m->base_virtual_addr, args, argp, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Linker::StartAllModules() {
|
void Linker::StartAllModules() {
|
||||||
|
@ -694,7 +689,7 @@ void Linker::Execute() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m->tls.image_virtual_addr != 0) {
|
if (m->tls.image_virtual_addr != 0) {
|
||||||
SetTLSStorage(m->tls.image_virtual_addr);
|
SetTLSStorage(m->tls.image_virtual_addr, m->tls.image_size);
|
||||||
}
|
}
|
||||||
RunMainEntry(m->elf.GetElfEntry() + m->base_virtual_addr, &p, ProgramExitFunc);
|
RunMainEntry(m->elf.GetElfEntry() + m->base_virtual_addr, &p, ProgramExitFunc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "core/loader/symbols_resolver.h"
|
#include "core/loader/symbols_resolver.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
using module_func_t = int (*)(size_t args, const void* argp);
|
|
||||||
struct DynamicModuleInfo;
|
struct DynamicModuleInfo;
|
||||||
class Linker;
|
class Linker;
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ struct LibraryInfo {
|
||||||
struct PS4ThreadLocal {
|
struct PS4ThreadLocal {
|
||||||
u64 image_virtual_addr = 0;
|
u64 image_virtual_addr = 0;
|
||||||
u64 image_size = 0;
|
u64 image_size = 0;
|
||||||
u64 handler_virtual_addr = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DynamicModuleInfo {
|
struct DynamicModuleInfo {
|
||||||
|
@ -103,27 +102,25 @@ struct DynamicModuleInfo {
|
||||||
|
|
||||||
// This struct keeps neccesary info about loaded modules. Main executeable is included too as well
|
// This struct keeps neccesary info about loaded modules. Main executeable is included too as well
|
||||||
struct Module {
|
struct Module {
|
||||||
Loader::Elf elf;
|
|
||||||
u64 aligned_base_size = 0;
|
u64 aligned_base_size = 0;
|
||||||
u64 base_virtual_addr = 0;
|
VAddr base_virtual_addr = 0;
|
||||||
u64 proc_param_virtual_addr = 0;
|
VAddr proc_param_virtual_addr = 0;
|
||||||
|
|
||||||
std::string file_name;
|
std::string file_name;
|
||||||
|
Loader::Elf elf;
|
||||||
std::vector<u8> m_dynamic;
|
std::vector<u8> m_dynamic;
|
||||||
std::vector<u8> m_dynamic_data;
|
std::vector<u8> m_dynamic_data;
|
||||||
DynamicModuleInfo dynamic_info{};
|
DynamicModuleInfo dynamic_info{};
|
||||||
|
|
||||||
Loader::SymbolsResolver export_sym;
|
Loader::SymbolsResolver export_sym;
|
||||||
Loader::SymbolsResolver import_sym;
|
Loader::SymbolsResolver import_sym;
|
||||||
|
|
||||||
PS4ThreadLocal tls;
|
PS4ThreadLocal tls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using ModuleFunc = int (*)(size_t, const void*);
|
||||||
|
|
||||||
class Linker {
|
class Linker {
|
||||||
public:
|
public:
|
||||||
Linker();
|
explicit Linker();
|
||||||
virtual ~Linker();
|
~Linker();
|
||||||
|
|
||||||
Module* LoadModule(const std::filesystem::path& elf_name);
|
Module* LoadModule(const std::filesystem::path& elf_name);
|
||||||
void LoadModuleToMemory(Module* m);
|
void LoadModuleToMemory(Module* m);
|
||||||
|
@ -143,7 +140,7 @@ private:
|
||||||
const ModuleInfo* FindModule(const Module& m, const std::string& id);
|
const ModuleInfo* FindModule(const Module& m, const std::string& id);
|
||||||
const LibraryInfo* FindLibrary(const Module& program, const std::string& id);
|
const LibraryInfo* FindLibrary(const Module& program, const std::string& id);
|
||||||
Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l);
|
Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l);
|
||||||
int StartModule(Module* m, size_t args, const void* argp, module_func_t func);
|
int StartModule(Module* m, size_t args, const void* argp, ModuleFunc func);
|
||||||
void StartAllModules();
|
void StartAllModules();
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Module>> m_modules;
|
std::vector<std::unique_ptr<Module>> m_modules;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/io_file.h"
|
#include "common/io_file.h"
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "core/aerolib/aerolib.h"
|
#include "core/aerolib/aerolib.h"
|
||||||
|
@ -52,8 +51,4 @@ void SymbolsResolver::DebugDump(const std::filesystem::path& file_name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int SymbolsResolver::GetSize() {
|
|
||||||
return m_symbols.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Core::Loader
|
} // namespace Core::Loader
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
|
@ -42,6 +42,10 @@ public:
|
||||||
void AddSymbol(const SymbolResolver& s, u64 virtual_addr);
|
void AddSymbol(const SymbolResolver& s, u64 virtual_addr);
|
||||||
const SymbolRecord* FindSymbol(const SymbolResolver& s) const;
|
const SymbolRecord* FindSymbol(const SymbolResolver& s) const;
|
||||||
|
|
||||||
|
size_t GetSize() const noexcept {
|
||||||
|
return m_symbols.size();
|
||||||
|
}
|
||||||
|
|
||||||
static std::string GenerateName(const SymbolResolver& s);
|
static std::string GenerateName(const SymbolResolver& s);
|
||||||
|
|
||||||
static std::string_view SymbolTypeToS(SymbolType sym_type) {
|
static std::string_view SymbolTypeToS(SymbolType sym_type) {
|
||||||
|
@ -60,7 +64,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugDump(const std::filesystem::path& file_name);
|
void DebugDump(const std::filesystem::path& file_name);
|
||||||
int GetSize();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<SymbolRecord> m_symbols;
|
std::vector<SymbolRecord> m_symbols;
|
||||||
|
|
|
@ -99,7 +99,7 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the mapping.
|
// Perform the mapping.
|
||||||
*out_addr = impl.Map(mapped_addr, size);
|
*out_addr = impl.Map(mapped_addr, size, alignment, phys_addr);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ public:
|
||||||
|
|
||||||
int MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
int MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
||||||
MemoryMapFlags flags, VMAType type, std::string_view name = "",
|
MemoryMapFlags flags, VMAType type, std::string_view name = "",
|
||||||
PAddr phys_addr = 0, u64 alignment = 0);
|
PAddr phys_addr = -1, u64 alignment = 0);
|
||||||
|
|
||||||
void UnmapMemory(VAddr virtual_addr, size_t size);
|
void UnmapMemory(VAddr virtual_addr, size_t size);
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ private:
|
||||||
VMAHandle FindVMA(VAddr target) {
|
VMAHandle FindVMA(VAddr target) {
|
||||||
// Return first the VMA with base >= target.
|
// Return first the VMA with base >= target.
|
||||||
const auto it = vma_map.lower_bound(target);
|
const auto it = vma_map.lower_bound(target);
|
||||||
if (it->first == target) {
|
if (it != vma_map.end() && it->first == target) {
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
return std::prev(it);
|
return std::prev(it);
|
||||||
|
|
|
@ -43,11 +43,20 @@ constexpr static TLSPattern TlsPatterns[] = {
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static DWORD slot = 0;
|
static DWORD slot = 0;
|
||||||
|
u8* tls_memory{};
|
||||||
|
u64 tls_image{};
|
||||||
|
u32 tls_image_size{};
|
||||||
|
|
||||||
void SetTLSStorage(u64 image_address) {
|
void SetTLSStorage(u64 image_address, u32 image_size) {
|
||||||
// Guest apps will use both positive and negative offsets to the TLS pointer.
|
// Guest apps will use both positive and negative offsets to the TLS pointer.
|
||||||
// User data at probably in negative offsets, while pthread data at positive offset.
|
// User data at probably in negative offsets, while pthread data at positive offset.
|
||||||
const BOOL result = TlsSetValue(slot, reinterpret_cast<LPVOID>(image_address));
|
if (tls_image == 0) {
|
||||||
|
tls_image = image_address;
|
||||||
|
tls_image_size = image_size;
|
||||||
|
}
|
||||||
|
tls_memory = (u8*)std::malloc(tls_image_size + 8192);
|
||||||
|
std::memcpy(tls_memory, reinterpret_cast<LPVOID>(tls_image), tls_image_size);
|
||||||
|
const BOOL result = TlsSetValue(slot, tls_memory + tls_image_size);
|
||||||
ASSERT(result != 0);
|
ASSERT(result != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +90,7 @@ void PatchTLS(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c) {
|
||||||
std::memcpy(&offset, code + tls_pattern.pattern_size, sizeof(u64));
|
std::memcpy(&offset, code + tls_pattern.pattern_size, sizeof(u64));
|
||||||
LOG_INFO(Core_Linker, "PATTERN64 FOUND at {}, reg: {} offset: {:#x}",
|
LOG_INFO(Core_Linker, "PATTERN64 FOUND at {}, reg: {} offset: {:#x}",
|
||||||
fmt::ptr(code), tls_pattern.target_reg, offset);
|
fmt::ptr(code), tls_pattern.target_reg, offset);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
ASSERT(offset == 0);
|
ASSERT(offset == 0);
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,14 @@ class CodeGenerator;
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
/// Sets the data pointer that contains the TLS image.
|
/// Sets the data pointer that contains the TLS image.
|
||||||
void SetTLSStorage(u64 image_address);
|
void SetTLSStorage(u64 image_address, u32 image_size);
|
||||||
|
|
||||||
/// Patches any instructions that access guest TLS to use provided storage.
|
/// Patches any instructions that access guest TLS to use provided storage.
|
||||||
void PatchTLS(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c);
|
void PatchTLS(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c);
|
||||||
|
|
||||||
|
class ThreadLocalStorage {
|
||||||
|
public:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
Loading…
Reference in New Issue