From 2b61a6760d7ef97b78d2ab214ae971fc78000d9d Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sun, 25 May 2025 20:22:56 -0400 Subject: [PATCH] Implement & link __osMalloc --- configure.py | 2 +- include/libc64/__osMalloc.h | 89 +++-- include/m_malloc.h | 2 +- src/game/m_malloc.c | 2 +- src/static/libc64/__osMalloc.c | 619 ++++++++++++++++++++++++++++++++- src/static/libc64/malloc.c | 2 +- 6 files changed, 662 insertions(+), 54 deletions(-) diff --git a/configure.py b/configure.py index ebd140c6..605de6a8 100644 --- a/configure.py +++ b/configure.py @@ -371,7 +371,7 @@ config.libs = [ "progress_category": "library", "src_dir": "src/static", "objects": [ - Object(NonMatching, "libc64/__osMalloc.c"), + Object(Matching, "libc64/__osMalloc.c"), Object(Matching, "libc64/aprintf.c"), Object(Matching, "libc64/math64.c"), Object(Matching, "libc64/qrand.c"), diff --git a/include/libc64/__osMalloc.h b/include/libc64/__osMalloc.h index 895b498d..e02e3291 100644 --- a/include/libc64/__osMalloc.h +++ b/include/libc64/__osMalloc.h @@ -7,62 +7,53 @@ #include "libultra/osMesg.h" #include "libultra/ultratypes.h" -struct ArenaNode; +#ifdef __cplusplus +extern "C" { +#endif // !__cplusplus -typedef struct Arena { - /* 0x00 */ struct ArenaNode* head; - /* 0x04 */ void* start; - /* 0x08 */ OSMesgQueue lockQueue; - /* 0x20 */ u8 unk_20; - /* 0x21 */ u8 isInit; - /* 0x22 */ u8 flag; - /* 0x24 */ u8 pad[0x2C - 0x24]; -} Arena; // size = 0x2C - -typedef struct ArenaNode { +typedef struct OSMemBlock_ { /* 0x00 */ s16 magic; - /* 0x02 */ s16 isFree; - /* 0x04 */ u32 size; - /* 0x08 */ struct ArenaNode* next; - /* 0x0C */ struct ArenaNode* prev; - /* 0x10 */ const char* filename; + /* 0x02 */ s16 free; + /* 0x04 */ s32 size; + /* 0x08 */ struct OSMemBlock_* next; + /* 0x0C */ struct OSMemBlock_* prev; + /* 0x10 */ const char* file; /* 0x14 */ s32 line; /* 0x18 */ OSId threadId; - /* 0x1C */ Arena* arena; + /* 0x1C */ struct OSArena_* arena; /* 0x20 */ OSTime time; - /* 0x28 */ u8 unk_28[0x30 - 0x28]; // probably padding -} ArenaNode; // size = 0x30 + /* 0x28 */ u8 pad[0x30 - 0x28]; +} OSMemBlock; // size = 0x30 -void setDebugInfo(ArenaNode*, const char*, s32, Arena*); -void arena_lock_init(Arena*); -void arena_lock(Arena*); -void arena_unlock(Arena*); -ArenaNode* get_block_next(ArenaNode*); -ArenaNode* get_block_prev(ArenaNode*); -ArenaNode* search_last_block(Arena*); -void __osMallocInit(Arena*, void*, u32); -void __osMallocAddBlock(Arena*, void*, s32); -void destroy_all_block(Arena*); -void __osMallocCleanup(Arena*); -BOOL __osMallocIsInitialized(Arena*); -void __osMalloc_FreeBlockTest(Arena*, ArenaNode*); -void* __osMallocALign_NoLock(Arena*, u32, u32); -void* __osMalloc_NoLock(Arena*, u32); -void* __osMallocAlign(Arena*, u32, u32); -void* __osMalloc(Arena*, u32); -void* __osMallocR(Arena*, u32); -void __osFree_NoLock(Arena*, void*); -void __osFree(Arena*, void*); -void* __osRealloc(Arena*, void*, u32); -int __osAnalayzeArena(Arena*, u32*); -void __osGetFreeArena(Arena*, u32*, u32*, u32*); -u32 __osGetTotalFreeSize(Arena*); -u32 __osGetFreeSize(Arena*); -u32 __osGetMemBlockSize(Arena*, void*); -void __osDisplayArena(Arena*); -int __osCheckArena(Arena*); -extern int __osMallocIsInitalized(Arena*); +typedef struct OSArena_ { + /* 0x00 */ OSMemBlock* head; + /* 0x04 */ u8* base; + /* 0x08 */ OSMessageQueue lockQueue; + /* 0x20 */ u8 _28; + /* 0x21 */ u8 initialized; + /* 0x22 */ u8 flags; +} OSArena; // size = 0x2C + +extern void __osMallocInit(OSArena* arena, u8* base, s32 size); +extern void __osMallocAddBlock(OSArena* arena, u8* base, s32 size); +extern void __osMallocCleanup(OSArena* arena); +extern BOOL __osMallocIsInitalized(OSArena* arena); +extern void* __osMallocAlign(OSArena* arena, u32 size, u32 align); +extern void* __osMalloc(OSArena* arena, u32 size); +extern void* __osMallocR(OSArena* arena, u32 size); +extern void __osFree(OSArena* arena, void* ptr); +extern void* __osRealloc(OSArena* arena, void* ptr, u32 size); +extern void __osGetFreeArena(OSArena* arena, u32* max_free_block_size, u32* free_blocks_size, u32* used_blocks_size); +extern u32 __osGetTotalFreeSize(OSArena* arena); +extern u32 __osGetFreeSize(OSArena* arena); +extern s32 __osGetMemBlockSize(OSArena* arena, void* ptr); +extern void __osDisplayArena(OSArena* arena); +extern int __osCheckArena(OSArena* arena); extern int __osMalloc_FreeBlockTest_Enable; +#ifdef __cplusplus +} +#endif // !__cplusplus + #endif diff --git a/include/m_malloc.h b/include/m_malloc.h index 5c7acfb9..40a6f972 100644 --- a/include/m_malloc.h +++ b/include/m_malloc.h @@ -8,7 +8,7 @@ extern "C" { #endif -extern Arena zelda_arena; +extern OSArena zelda_arena; extern void* zelda_malloc_align(size_t,u32); extern void* zelda_malloc(size_t); diff --git a/src/game/m_malloc.c b/src/game/m_malloc.c index 4899d6ab..2a66a88e 100644 --- a/src/game/m_malloc.c +++ b/src/game/m_malloc.c @@ -1,6 +1,6 @@ #include "m_malloc.h" -Arena zelda_arena; +OSArena zelda_arena; extern void* zelda_malloc_align(size_t size, u32 align) { return __osMallocAlign(&zelda_arena, size, align); diff --git a/src/static/libc64/__osMalloc.c b/src/static/libc64/__osMalloc.c index 8e7e0ffd..655e5903 100644 --- a/src/static/libc64/__osMalloc.c +++ b/src/static/libc64/__osMalloc.c @@ -1 +1,618 @@ -int __osMalloc_FreeBlockTest_Enable; +#include "libc64/__osMalloc.h" + +#include +#include "libultra/libultra.h" +#include "terminal.h" + +#define OS_MALLOC_MAGIC (s16)'ss' + +int __osMalloc_FreeBlockTest_Enable = FALSE; + +static void setDebugInfo(OSMemBlock* block, const char* file, s32 line, OSArena* arena) { + block->file = file; + block->line = line; + block->threadId = osGetThreadId(NULL); + block->arena = arena; + block->time = osGetTime(); +} + +static void arena_lock_init(OSArena* arena) { + static OSMesg arena_lock_msg; + + osCreateMesgQueue(&arena->lockQueue, &arena_lock_msg, OS_MESG_BLOCK); +} + +static void arena_lock(OSArena* arena) { + osSendMesg(&arena->lockQueue, NULL, OS_MESG_BLOCK); +} + +static void arena_unlock(OSArena* arena) { + osRecvMesg(&arena->lockQueue, NULL, OS_MESG_BLOCK); +} + +static OSMemBlock* get_block_next(OSMemBlock* block) { + // @BUG - this shouldn't check for block->next != NULL + if (block->next != NULL && (block->next == NULL || block->next->magic != OS_MALLOC_MAGIC)) { + OSReport(VT_COL(RED, WHITE) "緊急事態!メモリリーク発見! (block=%08x)\n" VT_RST, block->next); + OSPanic(__FILE__, 133, ""); + block->next = NULL; // @BUG - OSPanic halts CPU execution, this is pointless + } + + return block->next; +} + +static OSMemBlock* get_block_prev(OSMemBlock* block) { + // @BUG - this shouldn't check for block->prev != NULL + if (block->prev != NULL && (block->prev == NULL || block->prev->magic != OS_MALLOC_MAGIC)) { + OSReport(VT_COL(RED, WHITE) "緊急事態!メモリリーク発見! (block=%08x)\n" VT_RST, block->prev); + OSPanic(__FILE__, 144, ""); + block->prev = NULL; // @BUG - OSPanic halts CPU execution, this is pointless + } + + return block->prev; +} + +static OSMemBlock* search_last_block(OSArena* arena) { + OSMemBlock* block = NULL; + + if (arena != NULL) { + OSMemBlock* current = arena->head; + + if (current != NULL && current->magic == OS_MALLOC_MAGIC) { + while (current != NULL) { + block = current; + current = get_block_next(current); + } + } + } + + return block; +} + +extern void __osMallocInit(OSArena* arena, u8* base, s32 size) { + bzero(arena, sizeof(OSArena)); + arena_lock_init(arena); + __osMallocAddBlock(arena, base, size); + arena->initialized = TRUE; +} + +extern void __osMallocAddBlock(OSArena* arena, u8* base, s32 size) { + s32 align_size; + OSMemBlock* block; + OSMemBlock* last; + + if (base != NULL) { + block = (OSMemBlock*)ALIGN_NEXT((u32)base, 32); + align_size = ALIGN_PREV(size - ((u32)block - (u32)base), 32); + + if (align_size > (int)sizeof(OSMemBlock)) { + memset(block, 0xAB, align_size); + block->next = NULL; + block->prev = NULL; + block->size = align_size - sizeof(OSMemBlock); + block->free = TRUE; + block->magic = OS_MALLOC_MAGIC; + + arena_lock(arena); + last = search_last_block(arena); + if (last == NULL) { + arena->head = block; + arena->base = base; + } else { + block->prev = last; + last->next = block; + } + arena_unlock(arena); + } + } +} + +static void destroy_all_block(OSArena* arena) { + OSMemBlock* block; + OSMemBlock* next; + + arena_lock(arena); + block = arena->head; + while (block != NULL) { + next = get_block_next(block); + memset(block, 0xAB, block->size + sizeof(OSMemBlock)); + block = next; + } + arena_unlock(arena); +} + +extern void __osMallocCleanup(OSArena* arena) { + destroy_all_block(arena); + bzero(arena, sizeof(OSArena)); +} + +extern BOOL __osMallocIsInitalized(OSArena* arena) { + return arena->initialized; +} + +static void __osMalloc_FreeBlockTest(OSArena* arena, OSMemBlock* block) { + if (__osMalloc_FreeBlockTest_Enable) { + u32* s = (u32*)((u8*)block + sizeof(OSMemBlock)); + u32* e = (u32*)((u8*)block + sizeof(OSMemBlock) + block->size); + u32* p; + + for (p = s; p < e; p++) { + u32 v = *p; + + if (v != (u32)'\xAB\xAB\xAB\xAB' && v != (u32)'\xEF\xEF\xEF\xEF') { + OSReport(VT_COL(RED, WHITE) "緊急事態!メモリリーク検出! (block=%08x s=%08x e=%08x p=%08x)\n" VT_RST, block, s, e, p); + __osDisplayArena(arena); + OSPanic(__FILE__, 300, ""); + break; + } + } + } +} + +static void* __osMallocAlign_NoLock(OSArena* arena, u32 size, u32 align) { + OSMemBlock* aligned_block; + OSMemBlock* new_next; + int alignment_bytes; + OSMemBlock* block; + u8* data_p = NULL; + OSMemBlock* next; + u32 full_size; + u32 mask; + int remain; + + size = ALIGN_NEXT(size, 32); + full_size = ALIGN_NEXT(size, 32) + sizeof(OSMemBlock); + + if (align <= 16) { + align = 16; + } else if (align <= 32) { + align = 32; + } else if (align <= 64) { + align = 64; + } else if (align <= 128) { + align = 128; + } else if (align <= 256) { + align = 256; + } else if (align <= 1024) { + align = 1024; + } else { + align = 8; + } + + block = arena->head; + mask = align - 1; + while (block != NULL) { + if (block->free) { + remain = ((u32)block + sizeof(OSMemBlock)) & mask; + alignment_bytes = remain == 0 ? 0 : align - remain; + aligned_block = (OSMemBlock*)((u32)block + alignment_bytes); + + if (block->size - alignment_bytes >= size) { + if (arena->flags & 0x4) { + __osMalloc_FreeBlockTest(arena, block); + } + + if (block != aligned_block) { + memmove(aligned_block, block, sizeof(OSMemBlock)); + block = aligned_block; + block->size -= alignment_bytes; + if (block->prev != NULL) { + block->prev->next = block; + block->prev->size += alignment_bytes; // do not orphan alignment bytes + } else { + arena->head = block; + } + + if (block->next != NULL) { + block->next->prev = block; + } + } + + if (block->size > full_size) { + new_next = (OSMemBlock*)((u32)block + full_size); + new_next->next = get_block_next(block); + new_next->prev = block; + new_next->size = block->size - full_size; + new_next->free = TRUE; + new_next->magic = OS_MALLOC_MAGIC; + block->next = new_next; + block->size = size; + + next = get_block_next(new_next); + if (next != NULL) { + next->prev = new_next; + } + } + + block->free = FALSE; + setDebugInfo(block, NULL, 0, arena); + data_p = (u8*)block + sizeof(OSMemBlock); + if (arena->flags & 0x1) { + memset(data_p, 0xCD, size); + } + + break; + } + } + + block = get_block_next(block); + } + + return data_p; +} + +static void* __osMalloc_NoLock(OSArena* arena, u32 size) { + return __osMallocAlign_NoLock(arena, size, 0); +} + +extern void* __osMallocAlign(OSArena* arena, u32 size, u32 align) { + void* ret; + + arena_lock(arena); + ret = __osMallocAlign_NoLock(arena, size, align); + arena_unlock(arena); + return ret; +} + +extern void* __osMalloc(OSArena* arena, u32 size) { + return __osMallocAlign(arena, size, 0); +} + +extern void* __osMallocR(OSArena* arena, u32 size) { + OSMemBlock* block; + OSMemBlock* next; + OSMemBlock* n; + u8* ret = NULL; + u32 full_size; + + size = ALIGN_NEXT(size, 32); + full_size = ALIGN_NEXT(size, 32) + sizeof(OSMemBlock); + arena_lock(arena); + block = search_last_block(arena); + while (block != NULL) { + if (block->free && block->size >= size) { + if (arena->flags & 0x4) { + __osMalloc_FreeBlockTest(arena, block); + } + + if (block->size > full_size) { + next = (OSMemBlock*)((u32)block + block->size - size); + next->next = get_block_next(block); + next->prev = block; + next->size = size; + next->magic = OS_MALLOC_MAGIC; + block->next = next; + block->size -= full_size; + n = get_block_next(next); + if (n != NULL) { + n->prev = next; + } + block = next; + } + + block->free = FALSE; + setDebugInfo(block, NULL, 0, arena); + ret = (u8*)block + sizeof(OSMemBlock); + if (arena->flags & 0x1) { + memset(ret, 0xCD, size); + } + + break; + } + + block = get_block_prev(block); + } + + arena_unlock(arena); + return ret; +} + +static void __osFree_NoLock(OSArena* arena, void* ptr) { + OSMemBlock* block = (OSMemBlock*)((u32)ptr - sizeof(OSMemBlock)); + OSMemBlock* next; + OSMemBlock* prev; + OSMemBlock* temp; + + if (ptr != NULL) { + if (block == NULL || block->magic != OS_MALLOC_MAGIC) { + OSReport(VT_COL(RED, WHITE) "__osFree:不正解放(%08x)\n" VT_RST, ptr); // __osFree: irregular deallocation + OSPanic(__FILE__, 738, ""); + return; + } + + if (block->free) { + OSReport(VT_COL(RED, WHITE) "__osFree:二重解放(%08x)\n" VT_RST, ptr); // __osFree: double deallocation + OSPanic(__FILE__, 743, ""); + return; + } + + if (block->arena != arena && arena != NULL) { + OSReport(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena, block->arena); // __osFree: attempt to release memory in a different arena from where it was allocated + OSPanic(__FILE__, 750, ""); + return; + } + + next = get_block_next(block); + prev = get_block_prev(block); + block->free = TRUE; + setDebugInfo(block, NULL, 0, arena); + if (arena->flags & 0x2) { + memset((u8*)block + sizeof(OSMemBlock), 0xEF, block->size); + } + + if (next == (OSMemBlock*)((u32)block + sizeof(OSMemBlock) + block->size)) { + if (next->free) { + temp = get_block_next(next); + if (temp != NULL) { + temp->prev = block; + } + + block->size += next->size + sizeof(OSMemBlock); + if (arena->flags & 0x2) { + memset(next, 0xEF, sizeof(OSMemBlock)); + } + block->next = temp; + next = temp; + } + } + + if (prev != NULL && prev->free && block == (OSMemBlock*)((u32)prev + sizeof(OSMemBlock) + prev->size)) { + if (next != NULL) { + next->prev = prev; + } + + prev->next = next; + prev->size += block->size + sizeof(OSMemBlock); + if (arena->flags & 0x2) { + memset(block, 0xEF, sizeof(OSMemBlock)); + } + } + } +} + +extern void __osFree(OSArena* arena, void* ptr) { + arena_lock(arena); + __osFree_NoLock(arena, ptr); + arena_unlock(arena); +} + +// @fabricated, most likely suspect from DnM+'s symbol map +static void* __osFree_NoLock_DEBUG(OSArena* arena, void* ptr) { + OSReport(VT_COL(RED, WHITE) "__osFree:不正解放(%08x) [%s:%d ]\n" VT_RST); + OSReport(VT_COL(RED, WHITE) "__osFree:二重解放(%08x) [%s:%d ]\n" VT_RST); +} + +#pragma force_active on +extern void* __osRealloc(OSArena* arena, void* ptr, u32 size) { + void* new_ptr; + OSMemBlock* orig_block; + OSMemBlock* next; + OSMemBlock* temp; + OSMemBlock* new_next; + u32 full_size; + u32 need_size; + + orig_block = (OSMemBlock*)((u32)ptr - sizeof(OSMemBlock)); + size = ALIGN_NEXT(size, 32); + full_size = ALIGN_NEXT(size, 32) + sizeof(OSMemBlock); + + arena_lock(arena); + + if (ptr == NULL) { + ptr = __osMalloc_NoLock(arena, size); + } else if (size == 0) { + __osFree_NoLock(arena, ptr); + ptr = NULL; + } else if (size != orig_block->size) { + if (size > orig_block->size) { + next = get_block_next(orig_block); + need_size = size - orig_block->size; + if (next == (OSMemBlock*)((u32)orig_block + sizeof(OSMemBlock) + orig_block->size) && next->free && next->size >= need_size) { + OSMemBlock* new_next = (OSMemBlock*)((u32)next + need_size); + next->size -= need_size; + temp = get_block_next(next); + if (temp != NULL) { + temp->prev = new_next; + } + orig_block->next = new_next; + orig_block->size = size; + memmove(new_next, next, sizeof(OSMemBlock)); + } else { + new_ptr = __osMalloc_NoLock(arena, size); + if (new_ptr != NULL) { + memmove(new_ptr, ptr, orig_block->size); + __osFree_NoLock(arena, ptr); + } + ptr = new_ptr; + } + } else if (size < orig_block->size) { + next = get_block_next(orig_block); + if (next != NULL && next->free) { + OSMemBlock* new_next = (OSMemBlock*)((u32)orig_block + full_size); + *new_next = *next; + new_next->size += orig_block->size - size; + orig_block->next = new_next; + orig_block->size = size; + temp = get_block_next(new_next); + if (temp != NULL) { + temp->prev = new_next; + } + } else if (size + sizeof(OSMemBlock) < orig_block->size) { + new_next = (OSMemBlock*)((u32)orig_block + full_size); + new_next->next = get_block_next(orig_block); + new_next->prev = orig_block; + new_next->size = orig_block->size - full_size; + new_next->free = TRUE; + new_next->magic = OS_MALLOC_MAGIC; + orig_block->next = new_next; + orig_block->size = size; + temp = get_block_next(new_next); + if (temp != NULL) { + temp->prev = new_next; + } + } else { + ptr = NULL; + } + } + } + + arena_unlock(arena); + return ptr; +} +#pragma force_active reset + +static int __osAnalyzeArena(OSArena* arena, u32* ptr) { + OSMemBlock* block; + u32 max_free_block_size = 0; + u32 free_blocks_size = 0; + u32 free_blocks = 0; + u32 used_blocks_size = 0; + u32 used_blocks = 0; + + if (arena == NULL || ptr == NULL) { + return -1; + } + + arena_lock(arena); + + for (block = arena->head; block != NULL; block = get_block_next(block)) { + if (block->free) { + free_blocks++; + free_blocks_size += block->size; + if (max_free_block_size < block->size) { + max_free_block_size = block->size; + } + } else { + used_blocks++; + used_blocks_size += block->size; + } + } + + ptr[0] = max_free_block_size; + ptr[1] = free_blocks_size; + ptr[2] = free_blocks; + ptr[3] = used_blocks_size; + ptr[4] = used_blocks; + + arena_unlock(arena); + return 0; +} + +extern void __osGetFreeArena(OSArena* arena, u32* max_free_block_size, u32* free_blocks_size, u32* used_blocks_size) { + u32 data[5]; + + if (__osAnalyzeArena(arena, data) == 0) { + if (max_free_block_size != NULL) { + *max_free_block_size = data[0]; + } + + if (free_blocks_size != NULL) { + *free_blocks_size = data[1]; + } + + if (used_blocks_size != NULL) { + *used_blocks_size = data[3]; + } + } +} + +extern u32 __osGetTotalFreeSize(OSArena* arena) { + u32 total_free_size; + + __osGetFreeArena(arena, NULL, &total_free_size, NULL); + return total_free_size; +} + +#pragma force_active on +extern u32 __osGetFreeSize(OSArena* arena) { + u32 free_size; + + __osGetFreeArena(arena, &free_size, NULL, NULL); + return free_size; +} +#pragma force_active reset + +extern s32 __osGetMemBlockSize(OSArena* arena, void* ptr) { + OSMemBlock* block; + + if (ptr == NULL) { + return -1; + } + + block = (OSMemBlock*)((u32)ptr - sizeof(OSMemBlock)); + if (block != NULL && block->magic == OS_MALLOC_MAGIC) { + return block->size; + } + + return -1; +} + +extern void __osDisplayArena(OSArena* arena) { + OSMemBlock* block; + OSMemBlock* next; + u32 max_free; + u32 total_free; + u32 total_used; + + if (__osMallocIsInitalized(arena)) { + arena_lock(arena); + max_free = 0; + total_free = 0; + total_used = 0; + + OSReport("アリーナの内容 (0x%08x)\n", arena); + OSReport("メモリブロック範囲 status サイズ [時刻 s ms us ns: TID:src:行]\n"); + + block = arena->head; + while (block != NULL) { + if (block != NULL && block->magic == OS_MALLOC_MAGIC) { + next = block->next; + OSReport("%08x-%08x%c %s %08x", (u32)block, (u32)block + sizeof(OSMemBlock) + block->size, next == NULL ? '$' : (next->prev != block ? '!' : ' '), block->free ? "空き" : "確保", block->size); + if (!block->free) { + OSReport(" [%016llu:%2d:%s:%d]", OSTicksToMicroseconds((u64)block->time * 1000), block->threadId, block->file != NULL ? block->file : "**NULL**", block->line); + } + OSReport("\n"); + if (block->free) { + total_free += block->size; + if (max_free < block->size) { + max_free = block->size; + } + } else { + total_used += block->size; + } + } else { + OSReport("%08x Block Invalid\n", block); + next = NULL; + } + + block = next; + } + + OSReport("確保ブロックサイズの合計 0x%08x バイト\n", total_used); + OSReport("空きブロックサイズの合計 0x%08x バイト\n", total_free); + OSReport("最大空きブロックサイズ 0x%08x バイト\n", max_free); + arena_unlock(arena); + } +} + +#pragma force_active on +extern int __osCheckArena(OSArena* arena) { + int ret = FALSE; + OSMemBlock* block; + + arena_lock(arena); + block = arena->head; + while (block != NULL) { + if (block == NULL || block->magic != OS_MALLOC_MAGIC) { + OSReport(VT_COL(RED, WHITE) "おおっと!! (%08x %08x)\n" VT_RST, block, block->magic); + OSPanic(__FILE__, 1307, ""); + ret = TRUE; + break; + } + + block = get_block_next(block); + } + arena_unlock(arena); + return ret; +} +#pragma force_active reset diff --git a/src/static/libc64/malloc.c b/src/static/libc64/malloc.c index 3165dce2..5186fd87 100644 --- a/src/static/libc64/malloc.c +++ b/src/static/libc64/malloc.c @@ -1,7 +1,7 @@ #include "libc64/__osMalloc.h" #include "libc64/malloc.h" -Arena malloc_arena; +OSArena malloc_arena; extern void* malloc(size_t size) { return __osMalloc(&malloc_arena, size);