Fix resetting the trampoline data to avoid a crash when re-loading plugins 50+ times

This commit is contained in:
Maschell 2022-10-03 21:58:11 +02:00
parent 5303e05508
commit 0a254e59f4
3 changed files with 11 additions and 7 deletions

View File

@ -75,6 +75,11 @@ bool PluginManagement::doRelocation(const std::vector<std::unique_ptr<Relocation
bool PluginManagement::doRelocations(const std::vector<std::unique_ptr<PluginContainer>> &plugins, relocation_trampoline_entry_t *trampData, uint32_t tramp_size) {
for (uint32_t i = 0; i < tramp_size; i++) {
if (trampData[i].status == RELOC_TRAMP_IMPORT_DONE) {
trampData[i].status = RELOC_TRAMP_FREE;
}
}
for (auto &pluginContainer : plugins) {
DEBUG_FUNCTION_LINE_VERBOSE("Doing relocations for plugin: %s", pluginContainer->getMetaInformation()->getName().c_str());
if (!PluginManagement::doRelocation(pluginContainer->getPluginInformation()->getRelocationDataList(), trampData, tramp_size, pluginContainer->getPluginInformation()->getTrampolineId())) {

View File

@ -48,6 +48,7 @@ WUMS_APPLICATION_STARTS() {
if (upid != 2 && upid != 15) {
return;
}
OSReport("Running WiiUPluginLoaderBackend " VERSION_FULL "\n");
initLogging();
bool initNeeded = false;
@ -60,6 +61,7 @@ WUMS_APPLICATION_STARTS() {
DEBUG_FUNCTION_LINE_ERR("Failed to allocated the memory for the trampoline data");
OSFatal("Failed to allocated the memory for the trampoline data");
}
memset(gTrampData, 0, sizeof(relocation_trampoline_entry_t) * TRAMP_DATA_SIZE);
}
if (gLoadedPlugins.empty()) {
@ -68,8 +70,7 @@ WUMS_APPLICATION_STARTS() {
DEBUG_FUNCTION_LINE("Load plugins from %s", pluginPath.c_str());
auto pluginData = PluginDataFactory::loadDir(pluginPath);
gLoadedPlugins = PluginManagement::loadPlugins(pluginData, gTrampData, TRAMP_DATA_SIZE);
gLoadedPlugins = PluginManagement::loadPlugins(pluginData, gTrampData, TRAMP_DATA_SIZE);
initNeeded = true;
}
@ -80,8 +81,9 @@ WUMS_APPLICATION_STARTS() {
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_DEINIT_PLUGIN);
DEBUG_FUNCTION_LINE("Unload existing plugins.");
gLoadedPlugins.clear();
DEBUG_FUNCTION_LINE("Load new plugins");
memset(gTrampData, 0, sizeof(relocation_trampoline_entry_t) * TRAMP_DATA_SIZE);
DEBUG_FUNCTION_LINE("Load new plugins");
gLoadedPlugins = PluginManagement::loadPlugins(gLoadOnNextLaunch, gTrampData, TRAMP_DATA_SIZE);
initNeeded = true;
}

View File

@ -89,8 +89,7 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
// so they can be overridden/updated/reused on the next application launch.
//
// Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded.
if (trampoline_data[i].status == RELOC_TRAMP_FREE ||
trampoline_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
if (trampoline_data[i].status == RELOC_TRAMP_FREE) {
freeSlot = &(trampoline_data[i]);
break;
}
@ -117,11 +116,9 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des
freeSlot->trampoline[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampoline[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampoline[3] = 0x4E800420; // bctr
DCFlushRange((void *) freeSlot->trampoline, sizeof(freeSlot->trampoline));
ICInvalidateRange((unsigned char *) freeSlot->trampoline, sizeof(freeSlot->trampoline));
freeSlot->id = trampolineId;
DCFlushRange((void *) &freeSlot->id, sizeof(freeSlot->id));
ICInvalidateRange((unsigned char *) &freeSlot->id, sizeof(freeSlot->id));
if (reloc_type == RELOC_TYPE_FIXED) {