mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
loader: load libc automatically at startup
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "common/threads.h"
|
||||
#include "common/virtualMemory.h"
|
||||
#include "graphics/host_gpu/pageManager.h"
|
||||
#include "kernel/fileSystem.h"
|
||||
#include "kernel/memory.h"
|
||||
#include "kernel/pthread.h"
|
||||
#include "loader/elf.h"
|
||||
@@ -1264,7 +1265,9 @@ void RuntimeLinker::Execute(const std::filesystem::path& game_patch) {
|
||||
}
|
||||
#endif
|
||||
|
||||
PreloadAdjacentPrograms();
|
||||
// The runtime automatically loads libc; other PRXs are requested by the application.
|
||||
const auto libc_path = Libs::LibKernel::FileSystem::GetRealFilename("/app0/sce_module/libc.prx");
|
||||
auto* libc = Common::File::IsFileExisting(libc_path) ? LoadProgram(libc_path) : nullptr;
|
||||
RelocateAll();
|
||||
|
||||
if (!game_patch.empty()) {
|
||||
@@ -1273,7 +1276,9 @@ void RuntimeLinker::Execute(const std::filesystem::path& game_patch) {
|
||||
EXIT("Failed to apply game cheat\n");
|
||||
}
|
||||
}
|
||||
StartAllModules();
|
||||
if (libc != nullptr && libc->dynamic_info->init_vaddr != 0) {
|
||||
StartModule(libc, 0, nullptr, nullptr);
|
||||
}
|
||||
|
||||
LOGF_COLOR(Log::Color::BrightYellow, "---\n--- Execute: %s\n---\n", "Main");
|
||||
|
||||
@@ -1526,84 +1531,6 @@ void RuntimeLinker::StackTrace(uint64_t frame_ptr, uint64_t stack_ptr) {
|
||||
}
|
||||
}
|
||||
|
||||
static std::string GetProgramModuleName(const Program* program) {
|
||||
EXIT_IF(program == nullptr);
|
||||
|
||||
if (program->dynamic_info != nullptr && program->dynamic_info->so_name != nullptr &&
|
||||
program->dynamic_info->so_name[0] != '\0') {
|
||||
return std::string(program->dynamic_info->so_name);
|
||||
}
|
||||
|
||||
return Common::FilenameWithoutDirectory(Common::PathToGenericString(program->file_name));
|
||||
}
|
||||
|
||||
static bool ModuleStartDependenciesSatisfied(const Program* program,
|
||||
const std::vector<Program*>& programs,
|
||||
const std::vector<Program*>& started) {
|
||||
EXIT_IF(program == nullptr);
|
||||
EXIT_IF(program->dynamic_info == nullptr);
|
||||
|
||||
for (const auto* needed: program->dynamic_info->needed) {
|
||||
if (needed == nullptr || needed[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto needed_name = std::string(needed);
|
||||
|
||||
for (auto* dependency: programs) {
|
||||
if (dependency == nullptr || dependency == program || dependency->elf == nullptr ||
|
||||
!dependency->elf->IsShared()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto dependency_name = GetProgramModuleName(dependency);
|
||||
if (Common::EqualNoCase(dependency_name, needed_name) ||
|
||||
Common::EqualNoCase(Common::FilenameWithoutDirectory(
|
||||
Common::PathToGenericString(dependency->file_name)),
|
||||
needed_name)) {
|
||||
if (std::find(started.begin(), started.end(), dependency) == started.end()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RuntimeLinker::StartAllModules() {
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
std::vector<Program*> started;
|
||||
|
||||
for (;;) {
|
||||
bool progressed = false;
|
||||
|
||||
for (auto* p: m_programs) {
|
||||
if (p->elf->IsShared() && p->dynamic_info->init_vaddr != 0 &&
|
||||
std::find(started.begin(), started.end(), p) == started.end() &&
|
||||
ModuleStartDependenciesSatisfied(p, m_programs, started)) {
|
||||
StartModule(p, 0, nullptr, nullptr);
|
||||
started.push_back(p);
|
||||
progressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!progressed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* p: m_programs) {
|
||||
if (p->elf->IsShared() && p->dynamic_info->init_vaddr != 0 &&
|
||||
std::find(started.begin(), started.end(), p) == started.end()) {
|
||||
StartModule(p, 0, nullptr, nullptr);
|
||||
started.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeLinker::StopAllModules() {
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
@@ -1614,75 +1541,6 @@ void RuntimeLinker::StopAllModules() {
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsAdjacentModuleFile(const std::string& name) {
|
||||
auto lower = Common::ToLower(name);
|
||||
return lower.ends_with(".prx") || lower.ends_with(".sprx");
|
||||
}
|
||||
|
||||
static bool SkipAdjacentModuleFile(const std::string& name) {
|
||||
auto lower = Common::ToLower(name);
|
||||
return lower == "eboot.bin" || lower == "libkernel.prx" || lower == "libkernel_sys.prx";
|
||||
}
|
||||
|
||||
void RuntimeLinker::PreloadAdjacentPrograms() {
|
||||
if (m_programs.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> module_paths;
|
||||
|
||||
auto is_loaded = [this](const std::filesystem::path& path) {
|
||||
auto fixed_path = Common::FixFilenameSlash(Common::PathToGenericString(path));
|
||||
for (auto* program: m_programs) {
|
||||
if (Common::EqualNoCase(
|
||||
Common::FixFilenameSlash(Common::PathToGenericString(program->file_name)),
|
||||
fixed_path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto add_path = [&module_paths, &is_loaded](const std::filesystem::path& path) {
|
||||
if (is_loaded(path)) {
|
||||
return;
|
||||
}
|
||||
for (const auto& p: module_paths) {
|
||||
if (Common::EqualNoCase(Common::PathToGenericString(p),
|
||||
Common::PathToGenericString(path))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
module_paths.push_back(path);
|
||||
};
|
||||
|
||||
auto add_dir = [&add_path](const std::filesystem::path& dir) {
|
||||
if (!Common::File::IsDirectoryExisting(dir)) {
|
||||
return;
|
||||
}
|
||||
for (const auto& entry: Common::File::GetDirEntries(dir)) {
|
||||
if (entry.is_file && IsAdjacentModuleFile(entry.name) &&
|
||||
!SkipAdjacentModuleFile(entry.name)) {
|
||||
add_path(dir / entry.name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto root = m_programs.at(0)->file_name.parent_path();
|
||||
if (root.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_dir(root);
|
||||
add_dir(root / "sce_module");
|
||||
add_dir(root / "sce_modules");
|
||||
|
||||
for (const auto& path: module_paths) {
|
||||
auto* program = LoadProgram(path);
|
||||
program->fail_if_global_not_resolved = false;
|
||||
}
|
||||
}
|
||||
|
||||
int RuntimeLinker::StartModule(Program* program, size_t args, const void* argp,
|
||||
module_func_t func) {
|
||||
EXIT_IF(program == nullptr);
|
||||
@@ -2099,12 +1957,6 @@ void RuntimeLinker::ParseProgramDynamicInfo(Program* program) {
|
||||
EXIT_NOT_IMPLEMENTED(program->dynamic_info->debug != 0);
|
||||
EXIT_NOT_IMPLEMENTED(program->dynamic_info->textrel != 0);
|
||||
|
||||
std::vector<uint64_t> needed;
|
||||
GetDynValues(elf, &needed, DT_NEEDED);
|
||||
for (auto need: needed) {
|
||||
program->dynamic_info->needed.push_back(program->dynamic_info->str_table + need);
|
||||
}
|
||||
|
||||
uint64_t so_name = 0;
|
||||
GetDynValue(elf, &so_name, DT_SONAME);
|
||||
program->dynamic_info->so_name = program->dynamic_info->str_table + so_name;
|
||||
|
||||
@@ -102,11 +102,10 @@ struct DynamicInfo {
|
||||
|
||||
const char* so_name = nullptr;
|
||||
|
||||
std::vector<const char*> needed;
|
||||
std::vector<ModuleId> export_modules;
|
||||
std::vector<ModuleId> import_modules;
|
||||
std::vector<LibraryId> export_libs;
|
||||
std::vector<LibraryId> import_libs;
|
||||
std::vector<ModuleId> export_modules;
|
||||
std::vector<ModuleId> import_modules;
|
||||
std::vector<LibraryId> export_libs;
|
||||
std::vector<LibraryId> import_libs;
|
||||
};
|
||||
|
||||
struct Program {
|
||||
@@ -157,7 +156,6 @@ public:
|
||||
void Execute(const std::filesystem::path& game_patch = {});
|
||||
int StartModule(Program* program, size_t args, const void* argp, module_func_t func);
|
||||
int StopModule(Program* program, size_t args, const void* argp, module_func_t func);
|
||||
void StartAllModules();
|
||||
void StopAllModules();
|
||||
void DeleteTlss(int thread_id);
|
||||
void SetApplicationHeapApi(void* const api[10]);
|
||||
@@ -186,7 +184,6 @@ private:
|
||||
static void Relocate(Program* program);
|
||||
static void DeleteProgram(Program* program);
|
||||
static void SetupTlsHandler(Program* program);
|
||||
void PreloadAdjacentPrograms();
|
||||
|
||||
static const ModuleId* FindModule(const Program& program, const std::string& id);
|
||||
static const LibraryId* FindLibrary(const Program& program, const std::string& id);
|
||||
|
||||
Reference in New Issue
Block a user