Use non-newlib function to allocate memory for reent structs to make things simpler

This commit is contained in:
Maschell 2026-04-14 17:51:26 +02:00
parent a630031e97
commit 4ddd446d35
4 changed files with 26 additions and 54 deletions

View File

@ -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

View File

@ -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

View File

@ -9,13 +9,13 @@
#include <coreinit/thread.h>
#include <coreinit/cache.h>
#include <coreinit/memdefaultheap.h>
#include <coreinit/mutex.h>
#include <cstdlib>
#include <mutex>
#include <vector>
#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 {

View File

@ -1,13 +1,7 @@
#pragma once
#include <wums/reent_internal.h>
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();