Add WUMS 0.3.2 support

This commit is contained in:
Maschell 2023-01-06 18:04:26 +01:00
parent fae7ef0cee
commit f694372910
5 changed files with 50 additions and 33 deletions

View File

@ -1,5 +1,5 @@
FROM wiiuenv/devkitppc:20220917 FROM wiiuenv/devkitppc:20221228
COPY --from=wiiuenv/wiiumodulesystem:20221005 /artifacts $DEVKITPRO COPY --from=wiiuenv/wiiumodulesystem:20230106 /artifacts $DEVKITPRO
WORKDIR project WORKDIR project

View File

@ -231,17 +231,13 @@ bool CheckModulesByDependencies(const std::vector<std::shared_ptr<ModuleData>> &
for (auto const &curModule : loadedModules) { for (auto const &curModule : loadedModules) {
DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s", curModule->getExportName().c_str()); DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s", curModule->getExportName().c_str());
std::set<std::string> importsFromOtherModules; for (auto &curRPL : curModule->getDependencies()) {
for (const auto &curReloc : curModule->getRelocationDataList()) { if (!curRPL.starts_with("homebrew")) {
std::string curRPL = curReloc->getImportRPLInformation()->getRPLName(); continue;
}
if (curRPL == "homebrew_wupsbackend") { if (curRPL == "homebrew_wupsbackend") {
OSFatal("Error: module depends on homebrew_wupsbackend, this is not supported"); 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)) { if (!loaderModuleNames.contains(curRPL)) {
DEBUG_FUNCTION_LINE_VERBOSE("%s requires %s which is not loaded yet", curModule->getExportName().c_str(), curRPL.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("%s requires %s which is not loaded yet", curModule->getExportName().c_str(), curRPL.c_str());
return false; return false;
@ -256,35 +252,28 @@ bool CheckModulesByDependencies(const std::vector<std::shared_ptr<ModuleData>> &
std::vector<std::shared_ptr<ModuleData>> OrderModulesByDependencies(const std::vector<std::shared_ptr<ModuleData>> &loadedModules) { std::vector<std::shared_ptr<ModuleData>> OrderModulesByDependencies(const std::vector<std::shared_ptr<ModuleData>> &loadedModules) {
std::vector<std::shared_ptr<ModuleData>> finalOrder; std::vector<std::shared_ptr<ModuleData>> finalOrder;
std::vector<std::string_view> loadedModulesExportNames; std::set<std::string> loadedModulesExportNames;
std::vector<uint32_t> loadedModulesEntrypoints; std::set<uint32_t> loadedModulesEntrypoints;
while (true) { while (true) {
bool canBreak = true; bool canBreak = true;
bool weDidSomething = false; bool weDidSomething = false;
for (auto const &curModule : loadedModules) { for (auto const &curModule : loadedModules) {
if (std::find(loadedModulesEntrypoints.begin(), loadedModulesEntrypoints.end(), curModule->getEntrypoint()) != loadedModulesEntrypoints.end()) { if (loadedModulesEntrypoints.contains(curModule->getEntrypoint())) {
// DEBUG_FUNCTION_LINE("%s [%08X] is already loaded" curModule->getExportName().c_str(), curModule->getEntrypoint()); // DEBUG_FUNCTION_LINE("%s [%08X] is already loaded" curModule->getExportName().c_str(), curModule->getEntrypoint());
continue; continue;
} }
canBreak = false; canBreak = false;
DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s", curModule->getExportName().c_str()); DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s", curModule->getExportName().c_str());
std::vector<std::string_view> importsFromOtherModules; bool canLoad = true;
for (const auto &curReloc : curModule->getRelocationDataList()) { for (auto &curImportRPL : curModule->getDependencies()) {
std::string_view curRPL = curReloc->getImportRPLInformation()->getRPLName(); if (!curImportRPL.starts_with("homebrew")) {
if (curRPL == "homebrew_wupsbackend") { continue;
}
if (curImportRPL == "homebrew_wupsbackend") {
OSFatal("Error: module depends on homebrew_wupsbackend, this is not supported"); OSFatal("Error: module depends on homebrew_wupsbackend, this is not supported");
} }
if (curRPL.starts_with("homebrew")) { if (!loadedModulesExportNames.contains(curImportRPL)) {
if (std::find(importsFromOtherModules.begin(), importsFromOtherModules.end(), curRPL) == importsFromOtherModules.end()) {
DEBUG_FUNCTION_LINE_VERBOSE("%s is importing from %s", curModule->getExportName().c_str(), curRPL.begin());
importsFromOtherModules.push_back(curRPL);
}
}
}
bool canLoad = true;
for (auto &curImportRPL : importsFromOtherModules) {
if (std::find(loadedModulesExportNames.begin(), loadedModulesExportNames.end(), curImportRPL) == loadedModulesExportNames.end()) {
DEBUG_FUNCTION_LINE_VERBOSE("We can't load the module, because %s is not loaded yet", curImportRPL.begin()); DEBUG_FUNCTION_LINE_VERBOSE("We can't load the module, because %s is not loaded yet", curImportRPL.begin());
canLoad = false; canLoad = false;
break; break;
@ -294,8 +283,8 @@ std::vector<std::shared_ptr<ModuleData>> OrderModulesByDependencies(const std::v
weDidSomething = true; weDidSomething = true;
DEBUG_FUNCTION_LINE_VERBOSE("We can load: %s", curModule->getExportName().c_str()); DEBUG_FUNCTION_LINE_VERBOSE("We can load: %s", curModule->getExportName().c_str());
finalOrder.push_back(curModule); finalOrder.push_back(curModule);
loadedModulesExportNames.emplace_back(curModule->getExportName()); loadedModulesExportNames.insert(curModule->getExportName());
loadedModulesEntrypoints.push_back(curModule->getEntrypoint()); loadedModulesEntrypoints.insert(curModule->getEntrypoint());
} }
} }
if (canBreak) { if (canBreak) {

View File

@ -55,6 +55,7 @@ public:
} }
void addRelocationData(std::unique_ptr<RelocationData> relocation_data) { void addRelocationData(std::unique_ptr<RelocationData> relocation_data) {
addDependency(relocation_data->getImportRPLInformation()->getRPLName());
relocation_data_list.push_back(std::move(relocation_data)); relocation_data_list.push_back(std::move(relocation_data));
} }
@ -78,6 +79,14 @@ public:
return hook_data_list; return hook_data_list;
} }
void addDependency(std::string module_name) {
dependency_list.insert(std::move(module_name));
}
[[nodiscard]] const std::set<std::string> &getDependencies() const {
return dependency_list;
}
void addSectionInfo(std::shared_ptr<SectionInfo> sectionInfo) { void addSectionInfo(std::shared_ptr<SectionInfo> sectionInfo) {
section_info_list[sectionInfo->getName()] = std::move(sectionInfo); section_info_list[sectionInfo->getName()] = std::move(sectionInfo);
} }
@ -168,6 +177,7 @@ private:
std::vector<std::unique_ptr<RelocationData>> relocation_data_list; std::vector<std::unique_ptr<RelocationData>> relocation_data_list;
std::vector<std::unique_ptr<ExportData>> export_data_list; std::vector<std::unique_ptr<ExportData>> export_data_list;
std::vector<std::unique_ptr<HookData>> hook_data_list; std::vector<std::unique_ptr<HookData>> hook_data_list;
std::set<std::string> dependency_list;
std::set<std::shared_ptr<FunctionSymbolData>, FunctionSymbolDataComparator> symbol_data_list; std::set<std::shared_ptr<FunctionSymbolData>, FunctionSymbolDataComparator> symbol_data_list;
std::map<std::string_view, std::shared_ptr<SectionInfo>> section_info_list; std::map<std::string_view, std::shared_ptr<SectionInfo>> section_info_list;

View File

@ -79,7 +79,7 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
} else if ((address >= 0x10000000) && address < 0xC0000000) { } else if ((address >= 0x10000000) && address < 0xC0000000) {
data_size += sectionSize; data_size += sectionSize;
} }
if (psec->get_name().rfind(".wums.", 0) == 0) { if (psec->get_name().starts_with(".wums.")) {
data_size += sectionSize; data_size += sectionSize;
} }
} }
@ -196,6 +196,21 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
} }
} }
secInfo = moduleData->getSectionInfo(".wums.dependencies");
if (secInfo && secInfo.value()->getSize() > 0) {
if (secInfo.value()->getAddress() != 0) {
char *curEntry = (char *) secInfo.value()->getAddress();
while ((uint32_t) curEntry < (uint32_t) secInfo.value()->getAddress() + secInfo.value()->getSize()) {
if (*curEntry == '\0') {
curEntry++;
continue;
}
moduleData->addDependency(curEntry);
curEntry += strlen(curEntry) + 1;
}
}
}
secInfo = moduleData->getSectionInfo(".wums.hooks"); secInfo = moduleData->getSectionInfo(".wums.hooks");
if (secInfo && secInfo.value()->getSize() > 0) { if (secInfo && secInfo.value()->getSize() > 0) {
size_t entries_count = secInfo.value()->getSize() / sizeof(wums_hook_t); size_t entries_count = secInfo.value()->getSize() / sizeof(wums_hook_t);
@ -251,7 +266,7 @@ std::optional<std::shared_ptr<ModuleData>> ModuleDataFactory::load(const std::st
} }
} else if (key == "wums" || key == "wum") { } else if (key == "wums" || key == "wum") {
checkedVersion = true; checkedVersion = true;
if (value != "0.3.1") { if (value != "0.3.1" && values != "0.3.2") {
DEBUG_FUNCTION_LINE_WARN("Ignoring module - Unsupported WUMS version: %s.", value.c_str()); DEBUG_FUNCTION_LINE_WARN("Ignoring module - Unsupported WUMS version: %s.", value.c_str());
return std::nullopt; return std::nullopt;
} }

View File

@ -25,7 +25,8 @@ static const char **hook_names = (const char *[]){
"WUMS_HOOK_APPLICATION_STARTS", "WUMS_HOOK_APPLICATION_STARTS",
"WUMS_HOOK_APPLICATION_ENDS", "WUMS_HOOK_APPLICATION_ENDS",
"WUMS_HOOK_RELOCATIONS_DONE", "WUMS_HOOK_RELOCATIONS_DONE",
"WUMS_HOOK_APPLICATION_REQUESTS_EXIT"}; "WUMS_HOOK_APPLICATION_REQUESTS_EXIT",
"WUMS_HOOK_DEINIT"};
#endif #endif
void CallHook(const std::vector<std::shared_ptr<ModuleData>> &modules, wums_hook_type_t type, bool condition) { void CallHook(const std::vector<std::shared_ptr<ModuleData>> &modules, wums_hook_type_t type, bool condition) {
@ -68,8 +69,10 @@ void CallHook(const std::shared_ptr<ModuleData> &module, wums_hook_type_t type)
type == WUMS_HOOK_FINI_WUT_DEVOPTAB || type == WUMS_HOOK_FINI_WUT_DEVOPTAB ||
type == WUMS_HOOK_INIT_WUT_SOCKETS || type == WUMS_HOOK_INIT_WUT_SOCKETS ||
type == WUMS_HOOK_FINI_WUT_SOCKETS || type == WUMS_HOOK_FINI_WUT_SOCKETS ||
type == WUMS_HOOK_FINI_WUT_SOCKETS ||
type == WUMS_HOOK_INIT_WRAPPER || type == WUMS_HOOK_INIT_WRAPPER ||
type == WUMS_HOOK_FINI_WRAPPER)) { type == WUMS_HOOK_FINI_WRAPPER ||
type == WUMS_HOOK_DEINIT)) {
DEBUG_FUNCTION_LINE("Calling hook of type %s [%d] %d for %s: %08X", hook_names[type], type, curHook->getType(), module->getExportName().c_str(), curHook->getTarget()); DEBUG_FUNCTION_LINE("Calling hook of type %s [%d] %d for %s: %08X", hook_names[type], type, curHook->getType(), module->getExportName().c_str(), curHook->getTarget());
((void (*)())((uint32_t *) func_ptr))(); ((void (*)())((uint32_t *) func_ptr))();
break; break;