From 4ddd446d35bd41675d1cc6487e106cfb0502fc11 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 14 Apr 2026 17:51:26 +0200 Subject: [PATCH] Use non-newlib function to allocate memory for reent structs to make things simpler --- Dockerfile | 2 +- wumsloader/src/module/HooksManagement.cpp | 2 - wumsloader/src/utils/reent.cpp | 66 ++++++++--------------- wumsloader/src/utils/reent.h | 10 +--- 4 files changed, 26 insertions(+), 54 deletions(-) diff --git a/Dockerfile b/Dockerfile index a501977..1fae323 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM ghcr.io/wiiu-env/devkitppc:20260225 -COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:reentfix-dev-20260410-ae8bf4a /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:reentfix-dev-20260414-cd66e5f /artifacts $DEVKITPRO WORKDIR project diff --git a/wumsloader/src/module/HooksManagement.cpp b/wumsloader/src/module/HooksManagement.cpp index 6158d6c..2354f59 100644 --- a/wumsloader/src/module/HooksManagement.cpp +++ b/wumsloader/src/module/HooksManagement.cpp @@ -157,9 +157,7 @@ void CallHook(const ModuleContainer &module, wums_hook_type_t type) { } wums_loader_init_reent_args_t_ args; args.version = WUMS_REENT_CUR_API_VERSION; - args.restore_head_ptr = &wums_backend_restore_head; args.get_context_ptr = &wums_backend_get_context; - args.set_sentinel_ptr = &wums_backend_set_sentinel; args.add_reent_context_ptr = &wums_backend_register_context; // clang-format off diff --git a/wumsloader/src/utils/reent.cpp b/wumsloader/src/utils/reent.cpp index 30b91f6..5298180 100644 --- a/wumsloader/src/utils/reent.cpp +++ b/wumsloader/src/utils/reent.cpp @@ -9,13 +9,13 @@ #include #include +#include #include #include #include #include #define __WUMS_CONTEXT_THREAD_SPECIFIC_ID 0 -#define WUMS_REENT_ALLOC_SENTINEL ((__wums_reent_node *) 0xFFFFFFFF) #define WUMS_REENT_NODE_VERSION 1 #define WUMS_REENT_NODE_MAGIC 0x57554D53 // WUMS @@ -119,17 +119,15 @@ void ClearDanglingReentPtr() { { // Free everything that's currently in *sGlobalNodesCopy* - auto *oldHead = wums_backend_set_sentinel(); for (const auto nodeToFree : sGlobalNodesCopy) { if (nodeToFree->cleanupFn) { DEBUG_FUNCTION_LINE_VERBOSE("[%p] Call cleanupFn(%p) for node %p (dangling)", OSGetCurrentThread(), nodeToFree->reentPtr, nodeToFree); nodeToFree->cleanupFn(nodeToFree->reentPtr); } DEBUG_FUNCTION_LINE_VERBOSE("[%p] Free node %p (dangling)", OSGetCurrentThread(), nodeToFree); - free(nodeToFree); + MEMFreeToDefaultHeap(nodeToFree); } sGlobalNodesCopy.clear(); - wums_backend_restore_head(oldHead); } // Then move the node current list into sGlobalNodesCopy. @@ -140,18 +138,16 @@ void ClearDanglingReentPtr() { static void __wums_thread_cleanup(OSThread *thread, void *stack) { auto *head = static_cast<__wums_reent_node *>(wums_get_thread_specific(__WUMS_CONTEXT_THREAD_SPECIFIC_ID)); - if (!head || head == WUMS_REENT_ALLOC_SENTINEL || head->magic != WUMS_REENT_NODE_MAGIC) { + if (!head || head->magic != WUMS_REENT_NODE_MAGIC) { return; } OSThreadCleanupCallbackFn savedCleanup = head->savedCleanup; - // Set to effective global during free to prevent malloc re-entrancy loops - wums_set_thread_specific(__WUMS_CONTEXT_THREAD_SPECIFIC_ID, WUMS_REENT_ALLOC_SENTINEL); - auto *curr = head; while (curr) { __wums_reent_node *next = curr->next; + if (curr->magic == WUMS_REENT_NODE_MAGIC && curr->version >= 1) { if (curr->cleanupFn) { DEBUG_FUNCTION_LINE_VERBOSE("[%p] Call cleanupFn(%p) for node %p", thread, curr->reentPtr, curr); @@ -161,7 +157,7 @@ static void __wums_thread_cleanup(OSThread *thread, void *stack) { removeNodeFromListsSafe(curr); DEBUG_FUNCTION_LINE_VERBOSE("[%p] Free node %p", thread, curr); - free(curr); + MEMFreeToDefaultHeap(curr); } curr = next; @@ -176,57 +172,41 @@ static void __wums_thread_cleanup(OSThread *thread, void *stack) { } } -void *wums_backend_get_context(const void *moduleId, wums_loader_init_reent_errors_t_ *outError) { - if (!outError) { - OSFatal("Called wums_backend_get_context with error nullptr"); - return nullptr; +bool wums_backend_get_context(const void *moduleId, void **outPtr) { + if (!outPtr) { + return false; } + *outPtr = nullptr; + if (!OSGetCurrentThread()) { - *outError = WUMSReent_ERROR_NO_THREAD; - return nullptr; + return false; } - auto *head = static_cast<__wums_reent_node *>(wums_get_thread_specific(__WUMS_CONTEXT_THREAD_SPECIFIC_ID)); - - if (head == WUMS_REENT_ALLOC_SENTINEL) { - *outError = WUMSReent_ERROR_GLOBAL_REENT_REQUESTED; - return nullptr; - } + const auto *head = static_cast<__wums_reent_node *>(wums_get_thread_specific(__WUMS_CONTEXT_THREAD_SPECIFIC_ID)); if (head && head->magic != WUMS_REENT_NODE_MAGIC) { - *outError = WUMSReent_ERROR_GLOBAL_REENT_REQUESTED; - return nullptr; + return false; } const __wums_reent_node *curr = head; while (curr) { if (curr->version >= 1 && curr->moduleId == moduleId) { - return curr->reentPtr; + *outPtr = curr->reentPtr; + break; } curr = curr->next; } - *outError = WUMSReent_ERROR_NONE; - - return nullptr; + return true; } -void *wums_backend_set_sentinel() { - DEBUG_FUNCTION_LINE_VERBOSE("[%p] Set sentinel", OSGetCurrentThread()); - auto *head = wums_get_thread_specific(__WUMS_CONTEXT_THREAD_SPECIFIC_ID); - wums_set_thread_specific(__WUMS_CONTEXT_THREAD_SPECIFIC_ID, WUMS_REENT_ALLOC_SENTINEL); - return head; -} +bool wums_backend_register_context(const void *moduleId, void *reentPtr, void (*cleanupFn)(void *)) { + auto *oldHead = static_cast<__wums_reent_node *>(wums_get_thread_specific(__WUMS_CONTEXT_THREAD_SPECIFIC_ID)); + if (oldHead && (oldHead->magic != WUMS_REENT_NODE_MAGIC || oldHead->version < WUMS_REENT_NODE_VERSION)) { + return false; + } -void wums_backend_restore_head(void *oldHead) { - DEBUG_FUNCTION_LINE_VERBOSE("[%p] Set head to %p", OSGetCurrentThread(), oldHead); - wums_set_thread_specific(__WUMS_CONTEXT_THREAD_SPECIFIC_ID, oldHead); -} - -bool wums_backend_register_context(const void *moduleId, void *reentPtr, void (*cleanupFn)(void *), void *oldHeadVoid) { - auto *oldHead = static_cast<__wums_reent_node *>(oldHeadVoid); - - auto *newNode = static_cast<__wums_reent_node *>(malloc(sizeof(__wums_reent_node))); + auto *newNode = static_cast<__wums_reent_node *>(MEMAllocFromDefaultHeap(sizeof(__wums_reent_node))); if (!newNode) { return false; } @@ -239,7 +219,7 @@ bool wums_backend_register_context(const void *moduleId, void *reentPtr, void (* newNode->cleanupFn = cleanupFn; newNode->savedCleanup = nullptr; - if (oldHead == nullptr || oldHead == WUMS_REENT_ALLOC_SENTINEL || oldHead->magic != WUMS_REENT_NODE_MAGIC || oldHead->version < WUMS_REENT_NODE_VERSION) { + if (oldHead == nullptr || oldHead->magic != WUMS_REENT_NODE_MAGIC || oldHead->version < WUMS_REENT_NODE_VERSION) { DEBUG_FUNCTION_LINE_VERBOSE("[%p] Set OSSetThreadCleanupCallback for node %p", OSGetCurrentThread(), newNode); newNode->savedCleanup = OSSetThreadCleanupCallback(OSGetCurrentThread(), &__wums_thread_cleanup); } else { diff --git a/wumsloader/src/utils/reent.h b/wumsloader/src/utils/reent.h index e814060..2982830 100644 --- a/wumsloader/src/utils/reent.h +++ b/wumsloader/src/utils/reent.h @@ -1,13 +1,7 @@ #pragma once -#include +bool wums_backend_get_context(const void *pluginId, void **voidPtr); -void *wums_backend_get_context(const void *pluginId, wums_loader_init_reent_errors_t_ *outError); - -void *wums_backend_set_sentinel(); - -void wums_backend_restore_head(void *oldHead); - -bool wums_backend_register_context(const void *pluginId, void *reentPtr, void (*cleanupFn)(void *), void *oldHead); +bool wums_backend_register_context(const void *pluginId, void *reentPtr, void (*cleanupFn)(void *)); void ClearDanglingReentPtr(); \ No newline at end of file