mirror of
https://github.com/wiiu-env/WUMSLoader.git
synced 2026-05-06 05:15:32 -05:00
Use non-newlib function to allocate memory for reent structs to make things simpler
This commit is contained in:
parent
a630031e97
commit
4ddd446d35
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
Loading…
Reference in New Issue
Block a user