From 0031dbebbe00371b6fa987b70afcca0fe1714988 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 3 Jan 2023 22:36:14 +0100 Subject: [PATCH] Make sure the basemodule is one of the first modules --- wumsloader/src/entry.cpp | 39 +++++++++++++++++++++++++++++++++++- wumsloader/src/utils/utils.h | 15 ++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/wumsloader/src/entry.cpp b/wumsloader/src/entry.cpp index 084a144..5fa5a5e 100644 --- a/wumsloader/src/entry.cpp +++ b/wumsloader/src/entry.cpp @@ -8,10 +8,12 @@ #include "utils/dynamic.h" #include "utils/hooks.h" #include "utils/logger.h" +#include "utils/utils.h" #include "version.h" #include #include #include +#include #define VERSION "v0.2" @@ -128,7 +130,7 @@ void doStart(int argc, char **argv) { } } - // Make sure WUMS_HOOK_APPLICATION_ENDS and WUMS_HOOK_FINI_WUT are called + // Make sure aromaBaseModuleLoaded is loaded when WUMS_HOOK_APPLICATION_ENDS and WUMS_HOOK_FINI_WUT are called for (auto &curModule : gLoadedModules) { for (auto &curHook : curModule->getHookDataList()) { if (curHook->getType() == WUMS_HOOK_APPLICATION_ENDS || curHook->getType() == WUMS_HOOK_FINI_WUT_DEVOPTAB) { @@ -140,6 +142,41 @@ void doStart(int argc, char **argv) { } } + // Make sure the base module is called first of the "regular" modules (except the "InitBeforeRelocationDoneHook" hooks) + if (aromaBaseModuleLoaded) { + // Create a copy of all modules which do not call init before RelocationDoneHook + std::list> gLoadedModulesCopy; + for (auto &curModule : gLoadedModules) { + if (!curModule->isInitBeforeRelocationDoneHook()) { + gLoadedModulesCopy.push_back(curModule); + } + } + + // move homebrew_basemodule to the front + auto it = std::find_if(gLoadedModulesCopy.begin(), + gLoadedModulesCopy.end(), + [](auto &cur) { return std::string_view(cur->getExportName()) == "homebrew_basemodule"; }); + if (it != gLoadedModulesCopy.end()) { + auto module = *it; + gLoadedModulesCopy.erase(it); + gLoadedModulesCopy.push_front(module); + } + + // Move all modules which do not call init before RelocationDoneHook to the end, but keep homebrew_basemodule at the front. + for (auto &curModule : gLoadedModulesCopy) { + if (remove_first_if(gLoadedModules, [curModule](auto &cur) { return cur->getExportName() == curModule->getExportName(); })) { + gLoadedModules.push_back(curModule); + } + } + } + +#ifdef VERBOSE_DEBUG + DEBUG_FUNCTION_LINE_VERBOSE("Final order of modules"); + for (auto &curModule : gLoadedModules) { + DEBUG_FUNCTION_LINE_VERBOSE("%s", curModule->getExportName().c_str()); + } +#endif + DEBUG_FUNCTION_LINE_VERBOSE("Resolve relocations without replacing alloc functions"); ResolveRelocations(gLoadedModules, true, gUsedRPLs); diff --git a/wumsloader/src/utils/utils.h b/wumsloader/src/utils/utils.h index f334596..e7357b8 100644 --- a/wumsloader/src/utils/utils.h +++ b/wumsloader/src/utils/utils.h @@ -1,5 +1,7 @@ #pragma once #include +#include + template std::unique_ptr make_unique_nothrow(Args &&...args) noexcept(noexcept(T(std::forward(args)...))) { @@ -15,3 +17,16 @@ template std::shared_ptr make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward(args)...))) { return std::shared_ptr(new (std::nothrow) T(std::forward(args)...)); } + +template +bool remove_first_if(std::vector &list, Predicate pred) { + auto it = list.begin(); + while (it != list.end()) { + if (pred(*it)) { + list.erase(it); + return true; + } + it++; + } + return false; +} \ No newline at end of file