1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-12 09:50:50 +00:00
* libu64

* logutils.o -> debug.o in spec

* stackcheck.c is part of libu64

* review

* add paragraph about Overlay_Load calling an external function

* audio code*
This commit is contained in:
Dragorn421 2024-11-01 23:47:12 +01:00 committed by GitHub
parent 012c192f00
commit 5b27899b9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 97 additions and 29 deletions

View file

@ -1,127 +0,0 @@
#include "global.h"
#include "fault.h"
#include "terminal.h"
#if PLATFORM_N64 || OOT_DEBUG
f32 LogUtils_CheckFloatRange(const char* exp, int line, const char* valueName, f32 value, const char* minName, f32 min,
const char* maxName, f32 max) {
if (value < min || max < value) {
osSyncPrintf("%s %d: range error %s(%f) < %s(%f) < %s(%f)\n", exp, line, minName, min, valueName, value,
maxName, max);
}
return value;
}
#endif
#if OOT_DEBUG
s32 LogUtils_CheckIntRange(const char* exp, int line, const char* valueName, s32 value, const char* minName, s32 min,
const char* maxName, s32 max) {
if (value < min || max < value) {
PRINTF("%s %d: range error %s(%d) < %s(%d) < %s(%d)\n", exp, line, minName, min, valueName, value, maxName,
max);
}
return value;
}
void LogUtils_LogHexDump(void* ptr, s32 size0) {
u8* addr = (u8*)ptr;
s32 size = (s32)size0;
s32 rest;
s32 i;
u32 off;
PRINTF("dump(%08x, %u)\n", addr, size);
PRINTF("address off +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f 0123456789abcdef\n");
off = 0;
while (size > 0) {
PRINTF("%08x %04x", addr, off);
rest = (size < 0x10) ? size : 0x10;
i = 0;
while (true) {
if (i < rest) {
PRINTF(" %02x", *((u8*)addr + i));
} else {
PRINTF(" ");
}
i++;
if (i > 0xF) {
break;
}
}
PRINTF(" ");
i = 0;
while (true) {
if (i < rest) {
u8 a = *(addr + i);
PRINTF("%c", (a >= 0x20 && a < 0x7F) ? a : '.');
} else {
PRINTF(" ");
}
i++;
if (i > 0xF) {
break;
}
}
PRINTF("\n");
size -= rest;
addr += rest;
off += rest;
}
}
void LogUtils_LogPointer(s32 value, u32 max, void* ptr, const char* name, const char* file, int line) {
PRINTF(VT_COL(RED, WHITE) "%s %d %s[%d] max=%u ptr=%08x\n" VT_RST, file, line, name, value, max, ptr);
}
void LogUtils_CheckBoundary(const char* name, s32 value, s32 unk, const char* file, int line) {
u32 mask = (unk - 1);
if (value & mask) {
PRINTF(VT_COL(RED, WHITE) T("%s %d:%s(%08x) は バウンダリ(%d)違反です\n",
"%s %d:%s(%08x) is a boundary (%d) violation\n") VT_RST,
file, line, name, value, unk);
}
}
void LogUtils_CheckNullPointer(const char* exp, void* ptr, const char* file, int line) {
if (ptr == NULL) {
PRINTF(VT_COL(RED, WHITE) T("%s %d:%s は はヌルポインタです\n", "%s %d:%s is a null pointer\n") VT_RST, file,
line, exp);
}
}
void LogUtils_CheckValidPointer(const char* exp, void* ptr, const char* file, int line) {
if (ptr == NULL || (u32)ptr < 0x80000000 || (0x80000000 + osMemSize) <= (u32)ptr) {
PRINTF(VT_COL(RED, WHITE) T("%s %d:ポインタ %s(%08x) が異常です\n", "%s %d: Pointer %s(%08x) is invalid\n")
VT_RST,
file, line, exp, ptr);
}
}
void LogUtils_LogThreadId(const char* name, int line) {
PRINTF("<%d %s %d>", osGetThreadId(NULL), name, line);
}
#endif
void LogUtils_HungupThread(const char* name, int line) {
OSId threadId = osGetThreadId(NULL);
#if PLATFORM_N64 || OOT_DEBUG
osSyncPrintf("*** HungUp in thread %d, [%s:%d] ***\n", threadId, name, line);
#endif
Fault_AddHungupAndCrash(name, line);
}
void LogUtils_ResetHungup(void) {
#if PLATFORM_N64 || OOT_DEBUG
osSyncPrintf("*** Reset ***\n");
#endif
Fault_AddHungupAndCrash("Reset", 0);
}

View file

@ -1,212 +0,0 @@
#include "global.h"
#include "terminal.h"
StackEntry* sStackInfoListStart = NULL;
StackEntry* sStackInfoListEnd = NULL;
void StackCheck_Init(StackEntry* entry, void* stackBottom, void* stackTop, u32 initValue, s32 minSpace,
const char* name) {
StackEntry* iter;
u32* addr;
if (entry == NULL) {
sStackInfoListStart = NULL;
} else {
entry->head = stackBottom;
entry->tail = stackTop;
entry->initValue = initValue;
entry->minSpace = minSpace;
entry->name = name;
#if !PLATFORM_N64
iter = sStackInfoListStart;
while (iter) {
if (iter == entry) {
PRINTF(VT_COL(RED, WHITE) T("stackcheck_init: %08x は既にリスト中にある\n",
"stackcheck_init: %08x is already in the list\n") VT_RST,
entry);
return;
}
iter = iter->next;
}
#endif
entry->prev = sStackInfoListEnd;
entry->next = NULL;
if (sStackInfoListEnd) {
sStackInfoListEnd->next = entry;
}
sStackInfoListEnd = entry;
if (!sStackInfoListStart) {
sStackInfoListStart = entry;
}
if (entry->minSpace != -1) {
addr = entry->head;
while (addr < entry->tail) {
*addr++ = entry->initValue;
}
}
}
}
void StackCheck_Cleanup(StackEntry* entry) {
#if PLATFORM_N64
if (!entry->prev) {
sStackInfoListStart = entry->next;
} else {
entry->prev->next = entry->next;
}
if (!entry->next) {
sStackInfoListEnd = entry->prev;
}
#else
u32 inconsistency = false;
if (!entry->prev) {
if (entry == sStackInfoListStart) {
sStackInfoListStart = entry->next;
} else {
inconsistency = true;
}
} else {
entry->prev->next = entry->next;
}
if (!entry->next) {
if (entry == sStackInfoListEnd) {
sStackInfoListEnd = entry->prev;
} else {
inconsistency = true;
}
}
if (inconsistency) {
PRINTF(VT_COL(RED, WHITE) T("stackcheck_cleanup: %08x リスト不整合です\n",
"stackcheck_cleanup: %08x list inconsistent\n") VT_RST,
entry);
}
#endif
}
#if PLATFORM_N64
u32 StackCheck_Check(StackEntry* entry) {
if (entry == NULL) {
u32 ret = 0;
StackEntry* iter = sStackInfoListStart;
while (iter) {
u32 state = StackCheck_Check(iter);
if (state != STACK_STATUS_OK) {
ret = 1;
}
iter = iter->next;
}
return ret;
} else {
u32* last;
u32 used;
u32 free;
u32 ret;
for (last = entry->head; last < entry->tail; last++) {
if (entry->initValue != *last) {
break;
}
}
used = (uintptr_t)entry->tail - (uintptr_t)last;
free = (uintptr_t)last - (uintptr_t)entry->head;
if (free == 0) {
ret = STACK_STATUS_OVERFLOW;
} else if (free < (u32)entry->minSpace && entry->minSpace != -1) {
ret = STACK_STATUS_WARNING;
} else {
ret = STACK_STATUS_OK;
}
osSyncPrintf("head=%08x tail=%08x last=%08x used=%08x free=%08x [%s]\n", entry->head, entry->tail, last, used,
free, entry->name != NULL ? entry->name : "(null)");
return ret;
}
}
#else
u32 StackCheck_GetState(StackEntry* entry) {
u32* last;
u32 used;
u32 free;
u32 ret;
for (last = entry->head; last < entry->tail; last++) {
if (entry->initValue != *last) {
break;
}
}
used = (uintptr_t)entry->tail - (uintptr_t)last;
free = (uintptr_t)last - (uintptr_t)entry->head;
if (free == 0) {
ret = STACK_STATUS_OVERFLOW;
PRINTF(VT_FGCOL(RED));
} else if (free < (u32)entry->minSpace && entry->minSpace != -1) {
ret = STACK_STATUS_WARNING;
PRINTF(VT_FGCOL(YELLOW));
} else {
PRINTF(VT_FGCOL(GREEN));
ret = STACK_STATUS_OK;
}
#if !OOT_DEBUG
// This string is still in .rodata for retail builds
(void)"(null)";
#endif
PRINTF("head=%08x tail=%08x last=%08x used=%08x free=%08x [%s]\n", entry->head, entry->tail, last, used, free,
entry->name != NULL ? entry->name : "(null)");
PRINTF(VT_RST);
#if OOT_DEBUG
if (ret != STACK_STATUS_OK) {
LogUtils_LogHexDump(entry->head, (uintptr_t)entry->tail - (uintptr_t)entry->head);
}
#endif
return ret;
}
u32 StackCheck_CheckAll(void) {
u32 ret = 0;
StackEntry* iter = sStackInfoListStart;
while (iter) {
u32 state = StackCheck_GetState(iter);
if (state != STACK_STATUS_OK) {
ret = 1;
}
iter = iter->next;
}
return ret;
}
u32 StackCheck_Check(StackEntry* entry) {
if (entry == NULL) {
return StackCheck_CheckAll();
} else {
return StackCheck_GetState(entry);
}
}
#endif