linker: Reduce code nesting
This commit is contained in:
parent
4087a73145
commit
772891bfa7
|
@ -102,14 +102,14 @@ struct AddressSpace::Impl {
|
|||
|
||||
// Perform the map.
|
||||
void* ptr = nullptr;
|
||||
if (phys_addr) {
|
||||
if (phys_addr != -1) {
|
||||
ptr = MapViewOfFile3(backing_handle, process, reinterpret_cast<PVOID>(virtual_addr),
|
||||
phys_addr, size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||
} else {
|
||||
ptr = VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), size,
|
||||
MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||
}
|
||||
ASSERT(ptr);
|
||||
ASSERT_MSG(ptr, "{}", Common::GetLastErrorMsg());
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
* If zero is provided the mapping is considered as private.
|
||||
* @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.
|
||||
void Unmap(VAddr virtual_addr, size_t size);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <fmt/core.h>
|
||||
#include "common/assert.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
|
||||
namespace Core::FileSys {
|
||||
|
@ -51,9 +53,11 @@ std::string MntPoints::GetHostFile(const std::string& guest_file) {
|
|||
if (find == 0) {
|
||||
std::string npath = guest_file.substr(pair.guest_path.size(), guest_file.size() - 1);
|
||||
std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/');
|
||||
fmt::print("GetHostFile: {}\n", pair.host_path + npath);
|
||||
return pair.host_path + npath;
|
||||
}
|
||||
}
|
||||
UNREACHABLE();
|
||||
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 result = sceKernelStat(path, sb);
|
||||
return result;
|
||||
if (result < 0) {
|
||||
UNREACHABLE(); // TODO
|
||||
}
|
||||
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) {
|
||||
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
||||
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("1-LFLmRFxxM", "libkernel", 1, "libkernel", 1, 1, sceKernelMkdir);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
// memory
|
||||
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("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
||||
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!");
|
||||
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) {
|
||||
LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!");
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
|
@ -48,6 +48,10 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u
|
|||
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,
|
||||
s64 directMemoryStart, u64 alignment) {
|
||||
LOG_INFO(
|
||||
|
|
|
@ -39,6 +39,7 @@ struct OrbisQueryInfo {
|
|||
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize();
|
||||
int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len,
|
||||
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,
|
||||
s64 directMemoryStart, u64 alignment);
|
||||
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/kernel/thread_management.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/tls.h"
|
||||
#ifdef _WIN64
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
@ -82,6 +83,18 @@ int PS4_SYSV_ABI scePthreadAttrDestroy(ScePthreadAttr* attr) {
|
|||
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) {
|
||||
if (attr == nullptr || *attr == nullptr) {
|
||||
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) {
|
||||
// LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit");
|
||||
int result = scePthreadMutexInit(mutex, attr, nullptr);
|
||||
|
@ -829,6 +902,7 @@ static void cleanup_thread(void* arg) {
|
|||
static void* run_thread(void* arg) {
|
||||
auto* thread = static_cast<ScePthread>(arg);
|
||||
Common::SetCurrentThreadName(thread->name.c_str());
|
||||
Core::SetTLSStorage(0, 0);
|
||||
void* ret = nullptr;
|
||||
g_pthread_self = 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() {
|
||||
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("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait);
|
||||
// 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("7H0iTOciTLo", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
|
||||
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-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <time.h>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include "common/native_clock.h"
|
||||
#include "core/libraries/kernel/time_management.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
static u64 initial_ptc;
|
||||
|
@ -30,6 +37,57 @@ u64 PS4_SYSV_ABI sceKernelReadTsc() {
|
|||
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) {
|
||||
clock = std::make_unique<Common::NativeClock>();
|
||||
initial_ptc = clock->GetUptime();
|
||||
|
@ -39,6 +97,9 @@ void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
|||
sceKernelGetProcessTimeCounterFrequency);
|
||||
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
|
||||
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
|
||||
|
|
|
@ -11,11 +11,17 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
struct SceKernelTimeval {
|
||||
time_t tv_sec;
|
||||
s64 tv_usec;
|
||||
};
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
|
||||
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency();
|
||||
u64 PS4_SYSV_ABI sceKernelReadTsc();
|
||||
int PS4_SYSV_ABI sceKernelGettimeofday(SceKernelTimeval *tp);
|
||||
|
||||
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ Module* Linker::LoadModule(const std::filesystem::path& elf_name) {
|
|||
}
|
||||
|
||||
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_pheader = m->elf.GetProgramHeader();
|
||||
|
||||
|
@ -383,9 +383,7 @@ const LibraryInfo* Linker::FindLibrary(const Module& m, const std::string& id) {
|
|||
}
|
||||
|
||||
void Linker::LoadSymbols(Module* m) {
|
||||
|
||||
const auto symbol_database = [this](Module* m, Loader::SymbolsResolver* symbol,
|
||||
bool export_func) {
|
||||
const auto symbol_database = [this, m](Loader::SymbolsResolver* symbol, bool export_func) {
|
||||
if (m->dynamic_info.symbol_table == nullptr || m->dynamic_info.str_table == nullptr ||
|
||||
m->dynamic_info.symbol_table_total_size == 0) {
|
||||
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, &m->import_sym, false);
|
||||
symbol_database(&m->export_sym, true);
|
||||
symbol_database(&m->import_sym, false);
|
||||
}
|
||||
|
||||
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) {
|
||||
// std::scoped_lock lock{m_mutex};
|
||||
|
||||
for (auto& m : m_modules) {
|
||||
const auto& export_libs = m->dynamic_info.export_libs;
|
||||
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,
|
||||
Loader::SymbolRecord* return_info) {
|
||||
// std::scoped_lock lock{m_mutex};
|
||||
const auto ids = Common::SplitString(name, '#');
|
||||
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 {
|
||||
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* 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() {
|
||||
// std::scoped_lock lock{m_mutex};
|
||||
|
||||
for (auto& m : m_modules) {
|
||||
if (!m->elf.IsSharedLib()) {
|
||||
return m->proc_param_virtual_addr;
|
||||
|
@ -621,18 +615,19 @@ u64 Linker::GetProcParam() {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
using exit_func_t = PS4_SYSV_ABI void (*)();
|
||||
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,
|
||||
module_func_t func) {
|
||||
static PS4_SYSV_ABI int RunModule(uint64_t addr, size_t args, const void* argp,
|
||||
ModuleFunc 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);
|
||||
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() {
|
||||
|
@ -694,7 +689,7 @@ void Linker::Execute() {
|
|||
continue;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "core/loader/symbols_resolver.h"
|
||||
|
||||
namespace Core {
|
||||
using module_func_t = int (*)(size_t args, const void* argp);
|
||||
|
||||
struct DynamicModuleInfo;
|
||||
class Linker;
|
||||
|
||||
|
@ -56,7 +56,6 @@ struct LibraryInfo {
|
|||
struct PS4ThreadLocal {
|
||||
u64 image_virtual_addr = 0;
|
||||
u64 image_size = 0;
|
||||
u64 handler_virtual_addr = 0;
|
||||
};
|
||||
|
||||
struct DynamicModuleInfo {
|
||||
|
@ -103,27 +102,25 @@ struct DynamicModuleInfo {
|
|||
|
||||
// This struct keeps neccesary info about loaded modules. Main executeable is included too as well
|
||||
struct Module {
|
||||
Loader::Elf elf;
|
||||
u64 aligned_base_size = 0;
|
||||
u64 base_virtual_addr = 0;
|
||||
u64 proc_param_virtual_addr = 0;
|
||||
|
||||
VAddr base_virtual_addr = 0;
|
||||
VAddr proc_param_virtual_addr = 0;
|
||||
std::string file_name;
|
||||
|
||||
Loader::Elf elf;
|
||||
std::vector<u8> m_dynamic;
|
||||
std::vector<u8> m_dynamic_data;
|
||||
DynamicModuleInfo dynamic_info{};
|
||||
|
||||
Loader::SymbolsResolver export_sym;
|
||||
Loader::SymbolsResolver import_sym;
|
||||
|
||||
PS4ThreadLocal tls;
|
||||
};
|
||||
|
||||
using ModuleFunc = int (*)(size_t, const void*);
|
||||
|
||||
class Linker {
|
||||
public:
|
||||
Linker();
|
||||
virtual ~Linker();
|
||||
explicit Linker();
|
||||
~Linker();
|
||||
|
||||
Module* LoadModule(const std::filesystem::path& elf_name);
|
||||
void LoadModuleToMemory(Module* m);
|
||||
|
@ -143,7 +140,7 @@ private:
|
|||
const ModuleInfo* FindModule(const Module& m, const std::string& id);
|
||||
const LibraryInfo* FindLibrary(const Module& program, const std::string& id);
|
||||
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();
|
||||
|
||||
std::vector<std::unique_ptr<Module>> m_modules;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/io_file.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/types.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
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "common/types.h"
|
||||
|
||||
|
@ -42,6 +42,10 @@ public:
|
|||
void AddSymbol(const SymbolResolver& s, u64 virtual_addr);
|
||||
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_view SymbolTypeToS(SymbolType sym_type) {
|
||||
|
@ -60,7 +64,6 @@ public:
|
|||
}
|
||||
|
||||
void DebugDump(const std::filesystem::path& file_name);
|
||||
int GetSize();
|
||||
|
||||
private:
|
||||
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.
|
||||
*out_addr = impl.Map(mapped_addr, size);
|
||||
*out_addr = impl.Map(mapped_addr, size, alignment, phys_addr);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ public:
|
|||
|
||||
int MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
||||
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);
|
||||
|
||||
|
@ -121,7 +121,7 @@ private:
|
|||
VMAHandle FindVMA(VAddr target) {
|
||||
// Return first the VMA with base >= target.
|
||||
const auto it = vma_map.lower_bound(target);
|
||||
if (it->first == target) {
|
||||
if (it != vma_map.end() && it->first == target) {
|
||||
return it;
|
||||
}
|
||||
return std::prev(it);
|
||||
|
|
|
@ -43,11 +43,20 @@ constexpr static TLSPattern TlsPatterns[] = {
|
|||
|
||||
#ifdef _WIN32
|
||||
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.
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
LOG_INFO(Core_Linker, "PATTERN64 FOUND at {}, reg: {} offset: {:#x}",
|
||||
fmt::ptr(code), tls_pattern.target_reg, offset);
|
||||
continue;
|
||||
}
|
||||
ASSERT(offset == 0);
|
||||
|
||||
|
|
|
@ -12,9 +12,14 @@ class CodeGenerator;
|
|||
namespace Core {
|
||||
|
||||
/// 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.
|
||||
void PatchTLS(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c);
|
||||
|
||||
class ThreadLocalStorage {
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
|
Loading…
Reference in New Issue