linker: Reduce code nesting

This commit is contained in:
raphaelthegreat 2024-06-02 20:37:40 +03:00
parent 4087a73145
commit 772891bfa7
18 changed files with 274 additions and 84 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,9 +561,14 @@ 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) {
return_info->virtual_address = 0;
return_info->name = name;
LOG_ERROR(Core_Linker, "Not Resolved {}", name);
return;
}
const auto* library = FindLibrary(*m, ids.at(1)); const auto* library = FindLibrary(*m, ids.at(1));
const auto* module = FindModule(*m, ids.at(2)); const auto* module = FindModule(*m, ids.at(2));
ASSERT_MSG(library && module, "Unable to find library and module"); ASSERT_MSG(library && module, "Unable to find library and module");
@ -580,20 +582,20 @@ void Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Modul
sr.module_version_minor = module->version_minor; sr.module_version_minor = module->version_minor;
sr.type = sym_type; sr.type = sym_type;
const Loader::SymbolRecord* rec = nullptr; const auto* record = m_hle_symbols.FindSymbol(sr);
if (!record) {
rec = m_hle_symbols.FindSymbol(sr); // Check if it an export function
if (rec == nullptr) {
// check if it an export function
if (auto* p = FindExportedModule(*module, *library); if (auto* p = FindExportedModule(*module, *library);
p != nullptr && p->export_sym.GetSize() > 0) { p && p->export_sym.GetSize() > 0) {
rec = p->export_sym.FindSymbol(sr); record = p->export_sym.FindSymbol(sr);
} }
} }
if (rec != nullptr) { if (record) {
*return_info = *rec; *return_info = *record;
} else { return;
auto aeronid = AeroLib::FindByNid(sr.name.c_str()); }
const auto aeronid = AeroLib::FindByNid(sr.name.c_str());
if (aeronid) { if (aeronid) {
return_info->name = aeronid->name; return_info->name = aeronid->name;
return_info->virtual_address = AeroLib::GetStub(aeronid->nid); return_info->virtual_address = AeroLib::GetStub(aeronid->nid);
@ -604,16 +606,8 @@ void Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Modul
LOG_ERROR(Core_Linker, "Linker: Stub resolved {} as {} (lib: {}, mod: {})", sr.name, LOG_ERROR(Core_Linker, "Linker: Stub resolved {} as {} (lib: {}, mod: {})", sr.name,
return_info->name, library->name, module->name); return_info->name, library->name, module->name);
} }
} else {
return_info->virtual_address = 0;
return_info->name = name;
LOG_ERROR(Core_Linker, "Not Resolved {}", 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);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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