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

View File

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

View File

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

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

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

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!");
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(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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