From 2ca090345aa4c7db95018d6440570df5563bcf2d Mon Sep 17 00:00:00 2001 From: DH Date: Wed, 19 Jul 2023 23:28:23 +0300 Subject: [PATCH] [orbis-os] Fix freetype initialization --- orbis-kernel/include/orbis/module/Module.hpp | 4 +-- rpcsx-os/linker.cpp | 35 +++++++++++++++++--- rpcsx-os/ops.cpp | 9 +++-- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/orbis-kernel/include/orbis/module/Module.hpp b/orbis-kernel/include/orbis/module/Module.hpp index 6d4aa601c..cedc08cc5 100644 --- a/orbis-kernel/include/orbis/module/Module.hpp +++ b/orbis-kernel/include/orbis/module/Module.hpp @@ -18,7 +18,7 @@ struct Process; struct ModuleNeeded { utils::kstring name; std::uint16_t version; - std::uint16_t attr; + std::uint64_t attr; bool isExport; }; @@ -92,8 +92,8 @@ struct Module final { ptr pltGot{}; + uint64_t attributes{}; uint16_t version{}; - uint16_t attributes{}; uint16_t type{}; uint16_t flags{}; uint64_t entryPoint{}; diff --git a/rpcsx-os/linker.cpp b/rpcsx-os/linker.cpp index 500008dde..aea7c8a7c 100644 --- a/rpcsx-os/linker.cpp +++ b/rpcsx-os/linker.cpp @@ -571,6 +571,8 @@ Ref rx::linker::loadModule(std::span image, std::strncpy(result->moduleName, sceStrtab + static_cast(dyn.d_un.d_val), sizeof(result->moduleName)); + } else if (dyn.d_tag == kElfDynamicTypeSceModuleAttr) { + result->attributes = dyn.d_un.d_val; } if (dyn.d_tag == kElfDynamicTypeSoName) { @@ -585,7 +587,7 @@ Ref rx::linker::loadModule(std::span image, sceStrtab + static_cast(dyn.d_un.d_val)); if (name == "STREQUAL") { // HACK for broken FWs - result->needed.push_back("libSceDolbyVision"); + result->needed.push_back("libSceDolbyVision.prx"); } else { name = patchSoName(name); if (name != "libSceFreeTypeOptBm") { // TODO @@ -609,6 +611,7 @@ Ref rx::linker::loadModule(std::span image, auto &mod = result->neededModules[it->second]; mod.name = sceStrtab + static_cast(dyn.d_un.d_val); + mod.attr = static_cast(dyn.d_un.d_val >> 32); mod.isExport = false; } else if (dyn.d_tag == kElfDynamicTypeSceImportLib || dyn.d_tag == kElfDynamicTypeSceExportLib) { @@ -623,6 +626,18 @@ Ref rx::linker::loadModule(std::span image, lib.name = sceStrtab + static_cast(dyn.d_un.d_val); lib.isExport = dyn.d_tag == kElfDynamicTypeSceExportLib; + } else if (dyn.d_tag == kElfDynamicTypeSceExportLibAttr || + dyn.d_tag == kElfDynamicTypeSceImportLibAttr) { + auto [it, inserted] = idToLibraryIndex.try_emplace( + dyn.d_un.d_val >> 48, result->neededLibraries.size()); + + if (inserted) { + result->neededLibraries.emplace_back(); + } + + auto &lib = result->neededLibraries[it->second]; + + lib.attr = dyn.d_un.d_val & ((static_cast(1) << 48) - 1); } switch (dyn.d_tag) { @@ -800,9 +815,20 @@ Ref rx::linker::loadModule(std::span image, result->proc = process; - std::printf("Loaded module '%s' from object '%s', id: %u, address: %p - %p\n", - result->moduleName, result->soName, (unsigned)result->id, - result->base, (char *)result->base + result->size); + std::printf("Loaded module '%s' (%lx) from object '%s', address: %p - %p\n", + result->moduleName, (unsigned long)result->attributes, + result->soName, result->base, + (char *)result->base + result->size); + + for (auto mod : result->neededModules) { + std::printf(" needed module '%s' (%lx)\n", mod.name.c_str(), + (unsigned long)mod.attr); + } + + for (auto lib : result->neededLibraries) { + std::printf(" needed library '%s' (%lx), kind %s\n", lib.name.c_str(), + (unsigned long)lib.attr, lib.isExport ? "export" : "import"); + } if (tlsPhdrIndex >= 0 /* result->tlsSize != 0 */) { result->tlsIndex = process->nextTlsSlot++; @@ -877,7 +903,6 @@ static Ref createSceFreeTypeFull(orbis::Process *process) { result->initProc = reinterpret_cast(+[] {}); result->finiProc = reinterpret_cast(+[] {}); - result->id = process->modulesMap.insert(result); result->proc = process; return result; diff --git a/rpcsx-os/ops.cpp b/rpcsx-os/ops.cpp index 0a34eee01..a1124fe70 100644 --- a/rpcsx-os/ops.cpp +++ b/rpcsx-os/ops.cpp @@ -62,10 +62,11 @@ loadPrx(orbis::Thread *thread, std::string_view name, bool relocate, } } - std::printf("Loaded '%s'\n", module->soName); - loadedObjects[module->soName] = module.get(); - loadedModules[module->moduleName] = module.get(); + if (loadedModules.try_emplace(module->moduleName, module.get()).second) { + std::printf("Setting '%s' as '%s' module\n", module->soName, + module->moduleName); + } for (auto &needed : module->needed) { auto [result, neededModule] = @@ -98,6 +99,8 @@ loadPrx(orbis::Thread *thread, std::string_view name, bool relocate, } module->id = thread->tproc->modulesMap.insert(module); + std::fprintf(stderr, "'%s' ('%s') was loaded with id '%u'\n", + module->moduleName, module->soName, (unsigned)module->id); return {{}, module}; }