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

View File

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

View File

@ -55,6 +55,7 @@ public:
}
void addRelocationData(std::unique_ptr<RelocationData> relocation_data) {
addDependency(relocation_data->getImportRPLInformation()->getRPLName());
relocation_data_list.push_back(std::move(relocation_data));
}
@ -78,6 +79,14 @@ public:
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) {
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<ExportData>> export_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::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) {
data_size += sectionSize;
}
if (psec->get_name().rfind(".wums.", 0) == 0) {
if (psec->get_name().starts_with(".wums.")) {
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");
if (secInfo && secInfo.value()->getSize() > 0) {
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") {
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());
return std::nullopt;
}

View File

@ -25,7 +25,8 @@ static const char **hook_names = (const char *[]){
"WUMS_HOOK_APPLICATION_STARTS",
"WUMS_HOOK_APPLICATION_ENDS",
"WUMS_HOOK_RELOCATIONS_DONE",
"WUMS_HOOK_APPLICATION_REQUESTS_EXIT"};
"WUMS_HOOK_APPLICATION_REQUESTS_EXIT",
"WUMS_HOOK_DEINIT"};
#endif
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_INIT_WUT_SOCKETS ||
type == WUMS_HOOK_FINI_WUT_SOCKETS ||
type == WUMS_HOOK_FINI_WUT_SOCKETS ||
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());
((void (*)())((uint32_t *) func_ptr))();
break;