mirror of
https://github.com/wiiu-env/EnvironmentLoader.git
synced 2024-12-29 14:31:56 +01:00
Improve RPL loading when running the environment setup files
This commit is contained in:
parent
0c0d73ffa3
commit
5da6afb310
@ -3,28 +3,35 @@
|
|||||||
#include <coreinit/cache.h>
|
#include <coreinit/cache.h>
|
||||||
#include <coreinit/debug.h>
|
#include <coreinit/debug.h>
|
||||||
#include <coreinit/dynload.h>
|
#include <coreinit/dynload.h>
|
||||||
#include <coreinit/memdefaultheap.h>
|
|
||||||
|
|
||||||
#include "ElfUtils.h"
|
#include "ElfUtils.h"
|
||||||
#include "elfio/elfio.hpp"
|
#include "elfio/elfio.hpp"
|
||||||
|
|
||||||
bool ElfUtils::doRelocation(const std::vector<std::unique_ptr<RelocationData>> &relocData, relocation_trampoline_entry_t *tramp_data, uint32_t tramp_length) {
|
bool ElfUtils::doRelocation(const std::vector<std::unique_ptr<RelocationData>> &relocData, relocation_trampoline_entry_t *tramp_data, uint32_t tramp_length, std::map<std::string, OSDynLoad_Module> &usedRPls) {
|
||||||
for (auto const &curReloc : relocData) {
|
for (auto const &curReloc : relocData) {
|
||||||
std::string functionName = curReloc->getName();
|
std::string functionName = curReloc->getName();
|
||||||
std::string rplName = curReloc->getImportRPLInformation()->getRPLName();
|
std::string rplName = curReloc->getImportRPLInformation()->getRPLName();
|
||||||
int32_t isData = curReloc->getImportRPLInformation()->isData();
|
int32_t isData = curReloc->getImportRPLInformation()->isData();
|
||||||
OSDynLoad_Module rplHandle = nullptr;
|
OSDynLoad_Module rplHandle = nullptr;
|
||||||
|
|
||||||
|
if (!usedRPls.contains(rplName)) {
|
||||||
auto err = OSDynLoad_IsModuleLoaded(rplName.c_str(), &rplHandle);
|
DEBUG_FUNCTION_LINE_VERBOSE("Acquire %s", rplName.c_str());
|
||||||
if (err != OS_DYNLOAD_OK || rplHandle == nullptr) {
|
// Always acquire to increase refcount and make sure it won't get unloaded while we're using it.
|
||||||
// only acquire if not already loaded.
|
OSDynLoad_Error err = OSDynLoad_Acquire(rplName.c_str(), &rplHandle);
|
||||||
OSDynLoad_Acquire(rplName.c_str(), &rplHandle);
|
if (err != OS_DYNLOAD_OK) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Failed to acquire %s", rplName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Keep track RPLs we are using.
|
||||||
|
// They will be released on exit (See: AromaBaseModule)
|
||||||
|
usedRPls[rplName] = rplHandle;
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE_VERBOSE("Use from usedRPLs cache! %s", rplName.c_str());
|
||||||
}
|
}
|
||||||
|
rplHandle = usedRPls[rplName];
|
||||||
|
|
||||||
uint32_t functionAddress = 0;
|
uint32_t functionAddress = 0;
|
||||||
OSDynLoad_FindExport(rplHandle, (OSDynLoad_ExportType) isData, functionName.c_str(), (void **) &functionAddress);
|
if ((OSDynLoad_FindExport(rplHandle, (OSDynLoad_ExportType) isData, functionName.c_str(), (void **) &functionAddress) != OS_DYNLOAD_OK) || functionAddress == 0) {
|
||||||
if (functionAddress == 0) {
|
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to find export for %s %s %d", functionName.c_str(), rplName.c_str(), isData);
|
DEBUG_FUNCTION_LINE_ERR("Failed to find export for %s %s %d", functionName.c_str(), rplName.c_str(), isData);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
#include "common/relocation_defines.h"
|
#include "common/relocation_defines.h"
|
||||||
#include "module/RelocationData.h"
|
#include "module/RelocationData.h"
|
||||||
|
#include <coreinit/dynload.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -50,5 +52,5 @@ public:
|
|||||||
RelocationType reloc_type);
|
RelocationType reloc_type);
|
||||||
|
|
||||||
|
|
||||||
static bool doRelocation(const std::vector<std::unique_ptr<RelocationData>> &relocData, relocation_trampoline_entry_t *tramp_data, uint32_t tramp_length);
|
static bool doRelocation(const std::vector<std::unique_ptr<RelocationData>> &relocData, relocation_trampoline_entry_t *tramp_data, uint32_t tramp_length, std::map<std::string, OSDynLoad_Module> &usedRPls);
|
||||||
};
|
};
|
||||||
|
@ -180,6 +180,7 @@ int main(int argc, char **argv) {
|
|||||||
DirList setupModules(environment_path + "/modules/setup", ".rpx", DirList::Files, 1);
|
DirList setupModules(environment_path + "/modules/setup", ".rpx", DirList::Files, 1);
|
||||||
setupModules.SortList();
|
setupModules.SortList();
|
||||||
|
|
||||||
|
std::map<std::string, OSDynLoad_Module> usedRPls;
|
||||||
for (int i = 0; i < setupModules.GetFilecount(); i++) {
|
for (int i = 0; i < setupModules.GetFilecount(); i++) {
|
||||||
//! skip hidden linux and mac files
|
//! skip hidden linux and mac files
|
||||||
if (setupModules.GetFilename(i)[0] == '.' || setupModules.GetFilename(i)[0] == '_') {
|
if (setupModules.GetFilename(i)[0] == '.' || setupModules.GetFilename(i)[0] == '_') {
|
||||||
@ -206,7 +207,7 @@ int main(int argc, char **argv) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE("Loaded module data");
|
DEBUG_FUNCTION_LINE("Loaded module data");
|
||||||
if (!ElfUtils::doRelocation(moduleData.value()->getRelocationDataList(), gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH)) {
|
if (!ElfUtils::doRelocation(moduleData.value()->getRelocationDataList(), gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH, usedRPls)) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Relocations failed");
|
DEBUG_FUNCTION_LINE_ERR("Relocations failed");
|
||||||
OSFatal("EnvironmentLoader: Relocations failed");
|
OSFatal("EnvironmentLoader: Relocations failed");
|
||||||
} else {
|
} else {
|
||||||
@ -223,7 +224,14 @@ int main(int argc, char **argv) {
|
|||||||
((int(*)(int, char **)) moduleData.value()->getEntrypoint())(1, arr);
|
((int(*)(int, char **)) moduleData.value()->getEntrypoint())(1, arr);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
DEBUG_FUNCTION_LINE("Back from module");
|
DEBUG_FUNCTION_LINE("Back from module");
|
||||||
|
|
||||||
|
for (auto &rpl : usedRPls) {
|
||||||
|
DEBUG_FUNCTION_LINE_VERBOSE("Release %s", rpl.first.c_str());
|
||||||
|
OSDynLoad_Release(rpl.second);
|
||||||
|
}
|
||||||
|
usedRPls.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE("Return to Wii U Menu");
|
DEBUG_FUNCTION_LINE("Return to Wii U Menu");
|
||||||
ProcUIInit(OSSavesDone_ReadyToRelease);
|
ProcUIInit(OSSavesDone_ReadyToRelease);
|
||||||
|
Loading…
Reference in New Issue
Block a user