diff --git a/wumsloader/src/entry.cpp b/wumsloader/src/entry.cpp index 5fa5a5e..a7be141 100644 --- a/wumsloader/src/entry.cpp +++ b/wumsloader/src/entry.cpp @@ -19,6 +19,7 @@ void CallInitHooksForModule(const std::shared_ptr &curModule); +bool CheckModulesByDependencies(const std::vector> &loadedModules); std::vector> OrderModulesByDependencies(const std::vector> &loadedModules); // We need to wrap it to make sure the main function is called AFTER our code. @@ -170,6 +171,11 @@ void doStart(int argc, char **argv) { } } + // Check if dependencies are still resolved. + if (!CheckModulesByDependencies(gLoadedModules)) { + OSFatal("Module order is impossible"); + } + #ifdef VERBOSE_DEBUG DEBUG_FUNCTION_LINE_VERBOSE("Final order of modules"); for (auto &curModule : gLoadedModules) { @@ -220,6 +226,34 @@ void CallInitHooksForModule(const std::shared_ptr &curModule) { CallHook(curModule, WUMS_HOOK_INIT); } +bool CheckModulesByDependencies(const std::vector> &loadedModules) { + std::set loaderModuleNames; + + for (auto const &curModule : loadedModules) { + DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s", curModule->getExportName().c_str()); + std::set importsFromOtherModules; + for (const auto &curReloc : curModule->getRelocationDataList()) { + std::string curRPL = curReloc->getImportRPLInformation()->getRPLName(); + if (curRPL == "homebrew_wupsbackend") { + OSFatal("Error: module depends on homebrew_wupsbackend, this is not supported"); + } + if (curRPL.starts_with("homebrew")) { + importsFromOtherModules.insert(curRPL); + } + } + for (auto &curRPL : importsFromOtherModules) { + if (!loaderModuleNames.contains(curRPL)) { + DEBUG_FUNCTION_LINE_VERBOSE("%s requires %s which is not loaded yet", curModule->getExportName().c_str(), curRPL.c_str()); + return false; + } else { + DEBUG_FUNCTION_LINE_VERBOSE("Used %s, but it's already loaded", curRPL.c_str()); + } + } + loaderModuleNames.insert(curModule->getExportName()); + } + return true; +} + std::vector> OrderModulesByDependencies(const std::vector> &loadedModules) { std::vector> finalOrder; std::vector loadedModulesExportNames;