Add support for loading a list of plugin data on the next application change

This commit is contained in:
Maschell 2020-05-17 20:49:31 +02:00
parent db9b113eab
commit 9a5d3a843f
2 changed files with 64 additions and 0 deletions

View File

@ -92,6 +92,12 @@ struct plugin_information_t {
dyn_linking_relocation_data_t linking_data; // RPL and function name list dyn_linking_relocation_data_t linking_data; // RPL and function name list
}; };
struct plugin_information_on_reload_t {
int32_t number_used_plugins = 0; // Number of used plugins. Maximum is MAXIMUM_PLUGINS
plugin_data_t plugin_data[MAXIMUM_PLUGINS];
bool loadOnReload = false;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -25,6 +25,7 @@
#include "PluginManagement.h" #include "PluginManagement.h"
#include "globals.h" #include "globals.h"
#include <whb/sdcard.h> #include <whb/sdcard.h>
#include <plugin/PluginDataPersistence.h>
int test(); int test();
@ -53,6 +54,9 @@ int test() {
endAddress = curEndAddr; endAddress = curEndAddr;
} }
} }
memset((void *) &gLinkOnReload, 0, sizeof(gLinkOnReload));
// If this address is 0, make sure the header common match the one // If this address is 0, make sure the header common match the one
// in the SetupPayload repo. (I know that's a bad idea) // in the SetupPayload repo. (I know that's a bad idea)
endAddress = (endAddress + 0x100) & 0xFFFFFF00; endAddress = (endAddress + 0x100) & 0xFFFFFF00;
@ -88,6 +92,60 @@ int test() {
initNeeded = true; initNeeded = true;
} }
} }
if (gLinkOnReload.loadOnReload) {
DEBUG_FUNCTION_LINE("We would now swap the plugins");
std::vector<PluginData> pluginDataList;
for (int32_t i = 0; i < gLinkOnReload.number_used_plugins; i++) {
auto pluginData = PluginDataPersistence::load(&gLinkOnReload.plugin_data[i]);
pluginDataList.push_back(pluginData);
}
for (int32_t plugin_index = 0; plugin_index < gPluginInformation->number_used_plugins; plugin_index++) {
plugin_information_single_t *plugin = &(gPluginInformation->plugin_data[plugin_index]);
BOOL doDelete = true;
DEBUG_FUNCTION_LINE("Check if we can delete %08X", plugin->data.buffer);
for (auto &pluginData: pluginDataList) {
if (pluginData.getBuffer() == plugin->data.buffer) {
DEBUG_FUNCTION_LINE("We can keep buffer %08X", plugin->data.buffer);
doDelete = false;
break;
}
}
if (doDelete) {
if (plugin->data.buffer != nullptr) {
if (plugin->data.memoryType == eMemTypeMEM2) {
DEBUG_FUNCTION_LINE("free %08X", plugin->data.buffer);
free(plugin->data.buffer);
} else if (plugin->data.memoryType == eMemTypeExpHeap) {
DEBUG_FUNCTION_LINE("free %08X on EXP heap %08X", plugin->data.buffer, plugin->data.heapHandle);
MEMFreeToExpHeap((MEMHeapHandle) plugin->data.heapHandle, plugin->data.buffer);
} else {
DEBUG_FUNCTION_LINE("########################");
DEBUG_FUNCTION_LINE("Failed to free memory from plugin");
DEBUG_FUNCTION_LINE("########################");
}
plugin->data.buffer = NULL;
plugin->data.bufferLength = 0;
} else {
DEBUG_FUNCTION_LINE("Plugin has no copy of elf save in memory, can't free it");
}
}
}
DEBUG_FUNCTION_LINE("unloadPlugins");
PluginManagement::unloadPlugins(gPluginInformation, pluginDataHeap, false);
std::vector<PluginContainer> plugins = PluginManagement::loadPlugins(pluginDataList, pluginDataHeap, gPluginInformation->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH);
for (auto &pluginContainer : plugins) {
DEBUG_FUNCTION_LINE("Saving %s from %s", pluginContainer.getMetaInformation().getName().c_str(), pluginContainer.getMetaInformation().getAuthor().c_str());
if (!PluginContainerPersistence::savePlugin(gPluginInformation, pluginContainer)) {
DEBUG_FUNCTION_LINE("Failed to save plugin");
}
}
gLinkOnReload.loadOnReload = false;
initNeeded = true;
}
if (pluginDataHeap != NULL) { if (pluginDataHeap != NULL) {
std::vector<PluginContainer> plugins = PluginContainerPersistence::loadPlugins(gPluginInformation); std::vector<PluginContainer> plugins = PluginContainerPersistence::loadPlugins(gPluginInformation);