2022-02-04 16:25:44 +01:00
|
|
|
#include "PluginManagement.h"
|
2023-07-15 13:11:31 +02:00
|
|
|
#include "coreinit/interrupts.h"
|
|
|
|
#include "coreinit/scheduler.h"
|
2022-02-04 16:25:44 +01:00
|
|
|
#include "globals.h"
|
|
|
|
#include "hooks.h"
|
|
|
|
#include "patcher/hooks_patcher_static.h"
|
|
|
|
#include "plugin/PluginDataFactory.h"
|
2024-08-09 19:43:11 +02:00
|
|
|
#include "utils/DrawUtils.h"
|
2024-08-04 20:59:07 +02:00
|
|
|
#include "utils/WUPSBackendSettings.h"
|
2024-08-09 16:41:29 +02:00
|
|
|
#include "utils/input/VPADInput.h"
|
2024-11-27 20:44:36 +01:00
|
|
|
#include "utils/logger.h"
|
2022-02-14 20:26:32 +01:00
|
|
|
#include "utils/utils.h"
|
2024-11-27 20:44:20 +01:00
|
|
|
#include "version.h"
|
2024-11-27 20:44:36 +01:00
|
|
|
|
2022-02-04 16:25:44 +01:00
|
|
|
#include <coreinit/debug.h>
|
2023-08-16 10:08:44 +02:00
|
|
|
#include <notifications/notifications.h>
|
2024-11-27 20:44:20 +01:00
|
|
|
#include <ranges>
|
2022-02-04 16:25:44 +01:00
|
|
|
#include <wums.h>
|
2020-04-29 18:02:36 +02:00
|
|
|
|
2020-05-17 21:08:13 +02:00
|
|
|
WUMS_MODULE_EXPORT_NAME("homebrew_wupsbackend");
|
2021-04-07 00:23:23 +02:00
|
|
|
WUMS_USE_WUT_DEVOPTAB();
|
2023-01-07 13:29:53 +01:00
|
|
|
WUMS_DEPENDS_ON(homebrew_functionpatcher);
|
|
|
|
WUMS_DEPENDS_ON(homebrew_memorymapping);
|
2023-08-16 10:08:44 +02:00
|
|
|
WUMS_DEPENDS_ON(homebrew_notifications);
|
2021-09-17 16:45:11 +02:00
|
|
|
|
2024-08-09 19:43:11 +02:00
|
|
|
using namespace std::chrono_literals;
|
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
WUMS_INITIALIZE() {
|
2022-01-23 21:43:54 +01:00
|
|
|
initLogging();
|
2023-01-07 13:39:29 +01:00
|
|
|
|
|
|
|
if (FunctionPatcher_InitLibrary() != FUNCTION_PATCHER_RESULT_SUCCESS) {
|
|
|
|
OSFatal("homebrew_wupsbackend: FunctionPatcher_InitLibrary failed");
|
|
|
|
}
|
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
if (const NotificationModuleStatus res = NotificationModule_InitLibrary(); res != NOTIFICATION_MODULE_RESULT_SUCCESS) {
|
2023-11-04 15:32:45 +01:00
|
|
|
DEBUG_FUNCTION_LINE_ERR("Failed to init NotificationModule: %s (%d)", NotificationModule_GetStatusStr(res), res);
|
2023-08-16 10:08:44 +02:00
|
|
|
gNotificationModuleLoaded = false;
|
|
|
|
} else {
|
|
|
|
gNotificationModuleLoaded = true;
|
|
|
|
}
|
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
DEBUG_FUNCTION_LINE("Patching functions");
|
|
|
|
for (uint32_t i = 0; i < method_hooks_static_size; i++) {
|
2023-01-07 13:39:29 +01:00
|
|
|
if (FunctionPatcher_AddFunctionPatch(&method_hooks_static[i], nullptr, nullptr) != FUNCTION_PATCHER_RESULT_SUCCESS) {
|
|
|
|
OSFatal("homebrew_wupsbackend: Failed to AddPatch function");
|
2022-05-14 14:00:20 +02:00
|
|
|
}
|
2020-06-07 14:10:31 +02:00
|
|
|
}
|
2023-11-04 15:32:45 +01:00
|
|
|
|
2024-08-09 16:41:29 +02:00
|
|
|
VPadInput vpadInput;
|
|
|
|
vpadInput.update(1280, 720);
|
|
|
|
auto buttomComboSafeMode = Input::eButtons::BUTTON_L | Input::eButtons::BUTTON_UP | Input::eButtons::BUTTON_MINUS;
|
|
|
|
if ((vpadInput.data.buttons_h & (buttomComboSafeMode)) == buttomComboSafeMode) {
|
2024-08-10 09:42:13 +02:00
|
|
|
DrawUtils::RenderScreen([&vpadInput] {
|
2024-08-09 19:43:11 +02:00
|
|
|
DrawUtils::beginDraw();
|
|
|
|
DrawUtils::clear(COLOR_BACKGROUND_WARN);
|
|
|
|
DrawUtils::setFontColor(COLOR_WARNING);
|
|
|
|
|
|
|
|
// draw top bar
|
|
|
|
DrawUtils::setFontSize(48);
|
|
|
|
const char *title = "! Plugin System Safe Mode triggered !";
|
|
|
|
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(title) / 2, 48 + 8, title, true);
|
|
|
|
DrawUtils::drawRectFilled(8, 48 + 8 + 16, SCREEN_WIDTH - 8 * 2, 3, COLOR_WHITE);
|
|
|
|
|
|
|
|
DrawUtils::setFontSize(24);
|
|
|
|
const char *message = "The Safe Mode of the Plugin System has been triggered.";
|
|
|
|
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 - 48, message, true);
|
|
|
|
message = "Any plugins 3rd party plugins have been disabled!";
|
|
|
|
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 - 24, message, true);
|
|
|
|
|
|
|
|
message = "To enable them again, open the plugin config menu (\ue004 + \ue07a + \ue046).";
|
|
|
|
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 + 24, message, true);
|
2024-08-10 09:42:13 +02:00
|
|
|
message = "Then press \ue002 to manage active plugins";
|
2024-08-09 19:43:11 +02:00
|
|
|
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 + 48, message, true);
|
|
|
|
|
|
|
|
// draw bottom bar
|
|
|
|
DrawUtils::drawRectFilled(8, SCREEN_HEIGHT - 24 - 8 - 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_WHITE);
|
|
|
|
DrawUtils::setFontSize(18);
|
2024-08-10 09:42:13 +02:00
|
|
|
const char *exitHints = "Continuing in 10 seconds.";
|
2024-08-09 19:43:11 +02:00
|
|
|
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHints) / 2, SCREEN_HEIGHT - 8, exitHints, true);
|
|
|
|
|
|
|
|
DrawUtils::endDraw();
|
|
|
|
|
2024-08-10 09:42:13 +02:00
|
|
|
for (int i = 0; i < 10000 / 16; i++) {
|
|
|
|
vpadInput.update(1280, 720);
|
|
|
|
if ((vpadInput.data.buttons_d & (ANY_BUTTON_MASK))) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
std::this_thread::sleep_for(16ms);
|
|
|
|
}
|
2024-09-07 11:25:49 +02:00
|
|
|
DrawUtils::beginDraw();
|
|
|
|
DrawUtils::clear(COLOR_BLACK);
|
|
|
|
DrawUtils::endDraw();
|
2024-08-09 19:43:11 +02:00
|
|
|
});
|
2024-08-09 16:43:45 +02:00
|
|
|
DEBUG_FUNCTION_LINE_INFO("Safe Mode activated!");
|
2024-08-09 16:41:29 +02:00
|
|
|
auto tobeIgnoredFilePath = getNonBaseAromaPluginFilenames(getPluginPath());
|
|
|
|
WUPSBackendSettings::LoadSettings();
|
|
|
|
std::set<std::string> inactivePlugins = WUPSBackendSettings::GetInactivePluginFilenames();
|
|
|
|
|
|
|
|
inactivePlugins.insert(tobeIgnoredFilePath.begin(), tobeIgnoredFilePath.end());
|
|
|
|
for (const auto &d : inactivePlugins) {
|
2024-08-09 16:43:45 +02:00
|
|
|
DEBUG_FUNCTION_LINE_INFO("safemode: %s should be ignored", d.c_str());
|
2024-08-09 16:41:29 +02:00
|
|
|
}
|
|
|
|
WUPSBackendSettings::SetInactivePluginFilenames(inactivePlugins);
|
|
|
|
WUPSBackendSettings::SaveSettings();
|
|
|
|
}
|
|
|
|
|
2022-01-23 21:43:54 +01:00
|
|
|
deinitLogging();
|
2020-12-28 14:38:08 +01:00
|
|
|
}
|
|
|
|
|
2021-03-16 17:55:32 +01:00
|
|
|
WUMS_APPLICATION_REQUESTS_EXIT() {
|
2024-11-27 20:44:20 +01:00
|
|
|
const uint32_t upid = OSGetUPID();
|
2022-05-14 14:00:20 +02:00
|
|
|
if (upid != 2 && upid != 15) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT);
|
2021-03-16 17:55:32 +01:00
|
|
|
}
|
|
|
|
|
2020-12-28 14:38:08 +01:00
|
|
|
WUMS_APPLICATION_ENDS() {
|
2024-11-27 20:44:20 +01:00
|
|
|
const uint32_t upid = OSGetUPID();
|
2022-05-14 14:00:20 +02:00
|
|
|
if (upid != 2 && upid != 15) {
|
|
|
|
return;
|
2022-02-11 22:18:56 +01:00
|
|
|
}
|
2023-08-16 10:08:44 +02:00
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_APPLICATION_ENDS);
|
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_FINI_WUT_SOCKETS);
|
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB);
|
2022-02-11 22:19:27 +01:00
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
for (const auto &val : gUsedRPLs | std::views::values) {
|
|
|
|
OSDynLoad_Release(val);
|
2022-10-05 20:08:49 +02:00
|
|
|
}
|
|
|
|
gUsedRPLs.clear();
|
|
|
|
|
2022-02-14 20:24:41 +01:00
|
|
|
deinitLogging();
|
2020-04-29 18:02:36 +02:00
|
|
|
}
|
|
|
|
|
2024-03-24 07:40:58 +01:00
|
|
|
void CheckCleanupCallbackUsage(const std::vector<PluginContainer> &plugins);
|
2024-11-27 20:44:20 +01:00
|
|
|
void CleanupPlugins(std::vector<PluginContainer> &&pluginsToDeinit);
|
|
|
|
|
2021-04-01 00:37:22 +02:00
|
|
|
|
2020-06-03 18:21:43 +02:00
|
|
|
WUMS_APPLICATION_STARTS() {
|
2024-11-27 20:44:20 +01:00
|
|
|
const uint32_t upid = OSGetUPID();
|
2020-05-28 20:49:52 +02:00
|
|
|
if (upid != 2 && upid != 15) {
|
2020-06-03 18:21:43 +02:00
|
|
|
return;
|
2020-05-28 20:49:52 +02:00
|
|
|
}
|
2022-10-03 21:58:11 +02:00
|
|
|
|
2024-11-27 20:44:36 +01:00
|
|
|
OSReport("Running WiiUPluginLoaderBackend " MODULE_VERSION_FULL "\n");
|
2024-08-04 16:42:24 +02:00
|
|
|
gStoredTVBuffer = {};
|
|
|
|
gConfigMenuShouldClose = false;
|
2022-10-05 20:08:49 +02:00
|
|
|
|
|
|
|
gUsedRPLs.clear();
|
|
|
|
|
|
|
|
// If an allocated rpl was not released properly (e.g. if something else calls OSDynload_Acquire without releasing it) memory get leaked.
|
|
|
|
// Let's clean this up!
|
2023-11-04 15:32:45 +01:00
|
|
|
for (const auto &addr : gAllocatedAddresses) {
|
2022-10-05 20:08:49 +02:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("Memory allocated by OSDynload was not freed properly, let's clean it up! (%08X)", addr);
|
2024-11-27 20:44:20 +01:00
|
|
|
free(addr);
|
2022-10-05 20:08:49 +02:00
|
|
|
}
|
|
|
|
gAllocatedAddresses.clear();
|
|
|
|
|
2022-01-23 21:43:54 +01:00
|
|
|
initLogging();
|
2020-05-17 20:49:31 +02:00
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
std::lock_guard lock(gLoadedDataMutex);
|
2020-04-29 18:02:36 +02:00
|
|
|
|
2023-11-04 15:32:45 +01:00
|
|
|
if (gTrampData.empty()) {
|
|
|
|
gTrampData = std::vector<relocation_trampoline_entry_t>(TRAMP_DATA_SIZE);
|
|
|
|
for (auto &cur : gTrampData) {
|
|
|
|
cur.status = RELOC_TRAMP_FREE;
|
2022-05-14 14:00:20 +02:00
|
|
|
}
|
|
|
|
}
|
2021-04-01 00:37:22 +02:00
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
std::vector<PluginContainer> newLoadedPlugins;
|
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
if (gLoadedPlugins.empty()) {
|
2024-11-27 20:44:20 +01:00
|
|
|
const auto pluginPath = getPluginPath();
|
2021-01-10 13:17:47 +01:00
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
DEBUG_FUNCTION_LINE("Load plugins from %s", pluginPath.c_str());
|
2020-04-29 18:02:36 +02:00
|
|
|
|
2024-08-04 20:59:07 +02:00
|
|
|
WUPSBackendSettings::LoadSettings();
|
|
|
|
auto &inactiveList = WUPSBackendSettings::GetInactivePluginFilenames();
|
|
|
|
const auto pluginData = PluginDataFactory::loadDir(pluginPath, inactiveList);
|
2024-11-27 20:44:20 +01:00
|
|
|
newLoadedPlugins = PluginManagement::loadPlugins(pluginData, gTrampData);
|
2020-04-29 18:02:36 +02:00
|
|
|
}
|
2020-05-17 20:49:31 +02:00
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
if (!gLoadOnNextLaunch.empty()) {
|
2024-11-27 20:44:20 +01:00
|
|
|
std::vector<PluginContainer> pluginsToKeep;
|
2024-08-04 16:42:24 +02:00
|
|
|
std::vector<PluginLoadWrapper> toBeLoaded;
|
2024-11-27 20:44:20 +01:00
|
|
|
|
|
|
|
// Check which plugins are already loaded and which needs to be
|
2024-08-04 16:42:24 +02:00
|
|
|
for (const auto &pluginLoadWrapper : gLoadOnNextLaunch) {
|
2024-11-27 20:44:20 +01:00
|
|
|
// Check if the plugin data is already loaded
|
|
|
|
if (auto it = std::ranges::find_if(gLoadedPlugins,
|
2024-08-04 16:42:24 +02:00
|
|
|
[&pluginLoadWrapper](const PluginContainer &container) {
|
|
|
|
return container.getPluginDataCopy()->getHandle() == pluginLoadWrapper.getPluginData()->getHandle();
|
2024-11-27 20:44:20 +01:00
|
|
|
});
|
|
|
|
it != gLoadedPlugins.end()) {
|
|
|
|
pluginsToKeep.push_back(std::move(*it));
|
|
|
|
gLoadedPlugins.erase(it);
|
|
|
|
} else {
|
|
|
|
// Load it if it's not already loaded
|
2024-08-04 16:42:24 +02:00
|
|
|
toBeLoaded.push_back(pluginLoadWrapper);
|
2023-12-16 12:44:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
std::vector<PluginContainer> pluginsToDeinit = std::move(gLoadedPlugins);
|
|
|
|
gLoadedPlugins = std::move(pluginsToKeep);
|
|
|
|
|
|
|
|
DEBUG_FUNCTION_LINE("Deinit unused plugins");
|
|
|
|
CleanupPlugins(std::move(pluginsToDeinit));
|
2020-05-17 20:49:31 +02:00
|
|
|
|
2022-10-03 21:58:11 +02:00
|
|
|
DEBUG_FUNCTION_LINE("Load new plugins");
|
2024-11-27 20:44:20 +01:00
|
|
|
newLoadedPlugins = PluginManagement::loadPlugins(toBeLoaded, gTrampData);
|
2022-05-14 14:00:20 +02:00
|
|
|
}
|
2020-05-17 20:49:31 +02:00
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
DEBUG_FUNCTION_LINE("Clear plugin data lists.");
|
|
|
|
gLoadOnNextLaunch.clear();
|
|
|
|
gLoadedData.clear();
|
2020-05-17 20:49:31 +02:00
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
if (!gLoadedPlugins.empty() || !newLoadedPlugins.empty()) {
|
|
|
|
for (auto &pluginContainer : newLoadedPlugins) {
|
|
|
|
pluginContainer.setInitDone(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Move all new plugin containers into gLoadedPlugins
|
|
|
|
append_move_all_values(gLoadedPlugins, newLoadedPlugins);
|
|
|
|
|
2023-11-04 15:32:45 +01:00
|
|
|
if (!PluginManagement::doRelocations(gLoadedPlugins, gTrampData, gUsedRPLs)) {
|
2022-05-14 14:00:20 +02:00
|
|
|
DEBUG_FUNCTION_LINE_ERR("Relocations failed");
|
2023-11-04 15:32:45 +01:00
|
|
|
OSFatal("WiiUPluginLoaderBackend: Relocations failed.\n See crash logs for more information.");
|
2020-05-17 20:49:31 +02:00
|
|
|
}
|
2020-06-03 19:33:09 +02:00
|
|
|
// PluginManagement::memsetBSS(plugins);
|
2020-04-29 18:02:36 +02:00
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
const auto &needsInitsCheck = [](const PluginContainer &container) { return !container.isInitDone(); };
|
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_INIT_WUT_MALLOC, needsInitsCheck);
|
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_INIT_WUT_NEWLIB, needsInitsCheck);
|
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_INIT_WUT_STDCPP, needsInitsCheck);
|
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_INIT_WUT_DEVOPTAB);
|
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_INIT_WUT_SOCKETS);
|
2021-03-16 17:55:32 +01:00
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_INIT_WRAPPER, needsInitsCheck);
|
2022-01-23 21:16:38 +01:00
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
for (auto &plugin : gLoadedPlugins) {
|
|
|
|
if (plugin.isInitDone()) { continue; }
|
|
|
|
if (const WUPSStorageError err = plugin.OpenStorage(); err != WUPS_STORAGE_ERROR_SUCCESS) {
|
|
|
|
DEBUG_FUNCTION_LINE_ERR("Failed to open storage for plugin: %s. (%s)", plugin.getMetaInformation().getName().c_str(), WUPSStorageAPI_GetStatusStr(err));
|
2023-12-16 12:44:20 +01:00
|
|
|
}
|
2020-04-29 18:02:36 +02:00
|
|
|
}
|
2024-11-27 20:44:20 +01:00
|
|
|
PluginManagement::callInitHooks(gLoadedPlugins, needsInitsCheck);
|
2020-04-29 18:02:36 +02:00
|
|
|
|
2022-05-14 14:00:20 +02:00
|
|
|
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_APPLICATION_STARTS);
|
2024-11-27 20:44:20 +01:00
|
|
|
for (auto &pluginContainer : gLoadedPlugins) {
|
|
|
|
pluginContainer.setInitDone(true);
|
|
|
|
}
|
2021-04-01 00:37:22 +02:00
|
|
|
}
|
2023-07-15 13:11:31 +02:00
|
|
|
}
|
|
|
|
|
2024-11-27 20:44:20 +01:00
|
|
|
void CleanupPlugins(std::vector<PluginContainer> &&pluginsToDeinit) {
|
|
|
|
auto *currentThread = OSGetCurrentThread();
|
|
|
|
const auto saved_reent = currentThread->reserved[4];
|
|
|
|
const auto saved_cleanupCallback = currentThread->cleanupCallback;
|
|
|
|
|
|
|
|
currentThread->reserved[4] = 0;
|
|
|
|
|
|
|
|
CallHook(pluginsToDeinit, WUPS_LOADER_HOOK_DEINIT_PLUGIN);
|
|
|
|
|
|
|
|
CheckCleanupCallbackUsage(pluginsToDeinit);
|
|
|
|
|
|
|
|
if (currentThread->cleanupCallback != saved_cleanupCallback) {
|
|
|
|
DEBUG_FUNCTION_LINE_WARN("WUPS_LOADER_HOOK_DEINIT_PLUGIN overwrote the ThreadCleanupCallback, we need to restore it!\n");
|
|
|
|
OSSetThreadCleanupCallback(OSGetCurrentThread(), saved_cleanupCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
currentThread->reserved[4] = saved_reent;
|
|
|
|
|
|
|
|
DEBUG_FUNCTION_LINE("Restore function patches of plugins.");
|
|
|
|
PluginManagement::RestoreFunctionPatches(pluginsToDeinit);
|
|
|
|
|
|
|
|
for (auto &plugin : pluginsToDeinit) {
|
|
|
|
if (const WUPSStorageError err = plugin.CloseStorage(); err != WUPS_STORAGE_ERROR_SUCCESS) {
|
|
|
|
DEBUG_FUNCTION_LINE_ERR("Failed to close storage for plugin: %s", plugin.getMetaInformation().getName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &pluginContainer : pluginsToDeinit) {
|
|
|
|
for (auto &cur : gTrampData) {
|
2024-08-04 15:39:08 +02:00
|
|
|
if (!pluginContainer.isLinkedAndLoaded() || cur.id != pluginContainer.getPluginLinkInformation().getTrampolineId()) {
|
2024-11-27 20:44:20 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
cur.status = RELOC_TRAMP_FREE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-03-24 07:40:58 +01:00
|
|
|
void CheckCleanupCallbackUsage(const std::vector<PluginContainer> &plugins) {
|
2023-07-15 13:11:31 +02:00
|
|
|
auto *curThread = OSGetCurrentThread();
|
|
|
|
for (const auto &cur : plugins) {
|
2024-08-04 14:12:52 +02:00
|
|
|
if (!cur.isLinkedAndLoaded()) {
|
2024-08-03 17:23:27 +02:00
|
|
|
continue;
|
|
|
|
}
|
2024-08-04 14:12:52 +02:00
|
|
|
|
|
|
|
const auto textSection = cur.getPluginLinkInformation().getSectionInfo(".text");
|
2023-11-04 15:32:45 +01:00
|
|
|
if (!textSection) {
|
2023-07-15 13:11:31 +02:00
|
|
|
continue;
|
|
|
|
}
|
2024-11-27 20:44:20 +01:00
|
|
|
const uint32_t startAddress = textSection->getAddress();
|
|
|
|
const uint32_t endAddress = textSection->getAddress() + textSection->getSize();
|
|
|
|
auto *pluginName = cur.getMetaInformation().getName().c_str();
|
2023-07-15 13:11:31 +02:00
|
|
|
{
|
|
|
|
__OSLockScheduler(curThread);
|
2024-11-27 20:44:20 +01:00
|
|
|
const int state = OSDisableInterrupts();
|
|
|
|
OSThread *t = *reinterpret_cast<OSThread **>(0x100567F8);
|
2023-07-15 13:11:31 +02:00
|
|
|
while (t) {
|
2024-11-27 20:44:20 +01:00
|
|
|
const auto address = reinterpret_cast<uint32_t>(t->cleanupCallback);
|
2023-07-15 13:11:31 +02:00
|
|
|
if (address != 0 && address >= startAddress && address <= endAddress) {
|
|
|
|
OSReport("[WARN] PluginBackend: Thread 0x%08X is using a function from plugin %s for the threadCleanupCallback\n", t, pluginName);
|
|
|
|
}
|
|
|
|
t = t->activeLink.next;
|
|
|
|
}
|
|
|
|
OSRestoreInterrupts(state);
|
|
|
|
__OSUnlockScheduler(curThread);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|