diff --git a/include/global.h b/include/global.h index d90fe48..35261cd 100644 --- a/include/global.h +++ b/include/global.h @@ -28,8 +28,8 @@ void func_80080798(MtxF* mf, f32 /*x*/, f32 /*y*/); void func_80080C84(MtxF* mf, f32 /*x*/, f32 /*y*/, f32 /*z*/); // loadfragment2 -size_t Load2_LoadOverlay(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramStart, uintptr_t vramEnd, void* allocatedRamAddr); -void* Load2_AllocateAndLoad(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramStart, uintptr_t vramEnd); +size_t Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramStart, uintptr_t vramEnd, void* allocatedRamAddr); +void* Overlay_AllocateAndLoad(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramStart, uintptr_t vramEnd); #endif diff --git a/include/loadfragment2.h b/include/loadfragment2.h index 5c463d6..0d77c0a 100644 --- a/include/loadfragment2.h +++ b/include/loadfragment2.h @@ -14,6 +14,14 @@ #define R_MIPS_HI16 5 #define R_MIPS_LO16 6 +typedef enum { + /* 0 */ RELOC_SECTION_NULL, + /* 1 */ RELOC_SECTION_TEXT, + /* 2 */ RELOC_SECTION_DATA, + /* 3 */ RELOC_SECTION_RODATA, + /* 4 */ RELOC_SECTION_MAX +} RelocSectionId; + typedef struct { /* 0x00 */ u32 textSize; /* 0x04 */ u32 dataSize; diff --git a/include/terminal.h b/include/terminal.h new file mode 100644 index 0000000..f4ed8d6 --- /dev/null +++ b/include/terminal.h @@ -0,0 +1,40 @@ +#ifndef TERMINAL_H +#define TERMINAL_H + +// VT_: Helper macros for printing colored text to terminals, using ANSI escape codes +// VT stands for Virtual Terminal + +// 3-bit color codes +#define VT_COLOR_BLACK 0 +#define VT_COLOR_RED 1 +#define VT_COLOR_GREEN 2 +#define VT_COLOR_YELLOW 3 +#define VT_COLOR_BLUE 4 +#define VT_COLOR_MAGENTA 5 +#define VT_COLOR_CYAN 6 +#define VT_COLOR_WHITE 7 + +#define VT_COLOR_FOREGROUND 3 +#define VT_COLOR_BACKGROUND 4 + +#define VT_COLOR_EXPAND0(type, color) #type #color +#define VT_COLOR_EXPAND1(type, color) VT_COLOR_EXPAND0(type, color) +#define VT_COLOR(type, color) VT_COLOR_EXPAND1(VT_COLOR_##type, VT_COLOR_##color) + +#define VT_ESC "\x1b" +#define VT_CSI "[" +#define VT_CUP(x, y) VT_ESC VT_CSI y ";" x "H" +#define VT_ED(n) VT_ESC VT_CSI #n "J" +#define VT_SGR(n) VT_ESC VT_CSI n "m" + +// Add more macros if necessary +#define VT_COL(back, fore) VT_SGR(VT_COLOR(BACKGROUND, back) ";" VT_COLOR(FOREGROUND, fore)) +#define VT_FGCOL(color) VT_SGR(VT_COLOR(FOREGROUND, color)) +#define VT_BGCOL(color) VT_SGR(VT_COLOR(BACKGROUND, color)) +#define VT_RST VT_SGR("") +#define VT_CLS VT_ED(2) + +// ASCII BEL character, plays an alert tone +#define BEL '\a' + +#endif diff --git a/linker_scripts/us/symbol_addrs.txt b/linker_scripts/us/symbol_addrs.txt index ffc4c79..4084bf5 100644 --- a/linker_scripts/us/symbol_addrs.txt +++ b/linker_scripts/us/symbol_addrs.txt @@ -22,8 +22,8 @@ pad_press_stick_y = 0x8007FC0C; pad_correct_stick = 0x8007FC14; DoRelocation = 0x80081430; -Load2_LoadOverlay = 0x8008169C; -Load2_AllocateAndLoad = 0x80081744; // type:func +Overlay_Load = 0x8008169C; +Overlay_AllocateAndLoad = 0x80081744; // type:func MtxConv_F2L = 0x800817A0; MtxConv_L2F = 0x800818E8; @@ -75,7 +75,7 @@ csleep = 0x800821A0; // data gMtxClear = 0x800AA310; gMtxFClear = 0x800AA350; -gLoad2LogSeverity = 0x800AA390; // type:s32 +gOverlayLogSeverity = 0x800AA390; // type:s32 D_800B1E30 = 0x800B1E30; // diff --git a/src/main/loadfragment2.c b/src/main/loadfragment2.c index e21804e..5a96b84 100644 --- a/src/main/loadfragment2.c +++ b/src/main/loadfragment2.c @@ -9,7 +9,7 @@ #include "global.h" #include "loadfragment2.h" -s32 gLoad2LogSeverity = 2; +s32 gOverlayLogSeverity = 2; // Extract MIPS register rs from an instruction word #define MIPS_REG_RS(insn) (((insn) >> 0x15) & 0x1F) @@ -41,7 +41,7 @@ s32 gLoad2LogSeverity = 2; * @param vramStart Virtual RAM address that the overlay was compiled at. */ void DoRelocation(void* allocatedRamAddr, OverlayRelocationSection* ovl, uintptr_t vramStart) { - u32 sections[4]; + u32 sections[RELOC_SECTION_MAX]; u32* relocDataP; u32 reloc; uintptr_t relocatedAddress; @@ -49,18 +49,30 @@ void DoRelocation(void* allocatedRamAddr, OverlayRelocationSection* ovl, uintptr u32* luiInstRef; u32 allocu32 = (uintptr_t)allocatedRamAddr; u32* regValP; + //! MIPS ELF relocation does not generally require tracking register values, so at first glance it appears this + //! register tracking was an unnecessary complication. However there is a bug in the IDO compiler that can cause + //! relocations to be emitted in the wrong order under rare circumstances when the compiler attempts to reuse a + //! previous HI16 relocation for a different LO16 relocation as an optimization. This register tracking is likely + //! a workaround to prevent improper matching of unrelated HI16 and LO16 relocations that would otherwise arise + //! due to the incorrect ordering. u32* luiRefs[32]; u32 luiVals[32]; u32 isLoNeg; - if (gLoad2LogSeverity >= 3) {} + if (gOverlayLogSeverity >= 3) { + (void)"DoRelocation(%08x, %08x, %08x)\n"; + } - sections[0] = 0; - sections[1] = allocu32; - sections[2] = allocu32 + ovl->textSize; - sections[3] = sections[2] + ovl->dataSize; + sections[RELOC_SECTION_NULL] = 0; + sections[RELOC_SECTION_TEXT] = allocu32; + sections[RELOC_SECTION_DATA] = allocu32 + ovl->textSize; + sections[RELOC_SECTION_RODATA] = sections[RELOC_SECTION_DATA] + ovl->dataSize; for (i = 0; i < ovl->nRelocations; i++) { + // This will always resolve to a 32-bit aligned address as each section + // containing code or pointers must be aligned to at least 4 bytes and the + // MIPS ABI defines the offset of both 16-bit and 32-bit relocations to be + // the start of the 32-bit word containing the target. reloc = ovl->relocations[i]; relocDataP = (u32*)(sections[RELOC_SECTION(reloc)] + RELOC_OFFSET(reloc)); @@ -72,7 +84,9 @@ void DoRelocation(void* allocatedRamAddr, OverlayRelocationSection* ovl, uintptr // Check address is valid for relocation if ((*relocDataP & 0x0F000000) == 0) { *relocDataP = *relocDataP - vramStart + allocu32; - } else if (gLoad2LogSeverity >= 3) { + } else if (gOverlayLogSeverity >= 3) { + // "Segment pointer 32 %08x" + (void)"セグメントポインタ32です %08x\n"; } break; @@ -85,6 +99,9 @@ void DoRelocation(void* allocatedRamAddr, OverlayRelocationSection* ovl, uintptr *relocDataP = (*relocDataP & 0xFC000000) | (((PHYS_TO_K0(MIPS_JUMP_TARGET(*relocDataP)) - vramStart + allocu32) & 0x0FFFFFFF) >> 2); + } else if (gOverlayLogSeverity >= 3) { + // "Segment pointer 26 %08x" + (void)"セグメントポインタ26です %08x\n"; } break; @@ -113,35 +130,53 @@ void DoRelocation(void* allocatedRamAddr, OverlayRelocationSection* ovl, uintptr isLoNeg = (relocatedAddress & 0x8000) ? 1 : 0; *luiInstRef = (*luiInstRef & 0xFFFF0000) | (((relocatedAddress >> 0x10) & 0xFFFF) + isLoNeg); *relocDataP = (*relocDataP & 0xFFFF0000) | (relocatedAddress & 0xFFFF); - } else if (gLoad2LogSeverity >= 3) { + } else if (gOverlayLogSeverity >= 3) { + // "Segment pointer 16 %08x %08x %08x" + (void)"セグメントポインタ16です %08x %08x %08x\n"; } break; } } } -size_t Load2_LoadOverlay(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramStart, uintptr_t vramEnd, - void* allocatedRamAddr) { +size_t Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramStart, uintptr_t vramEnd, + void* allocatedRamAddr) { UNUSED s32 pad[2]; s32 size = vromEnd - vromStart; void* end; OverlayRelocationSection* ovl; - if (gLoad2LogSeverity >= 3) {} - if (gLoad2LogSeverity >= 3) {} + if (gOverlayLogSeverity >= 3) { + // "Start loading dynamic link function" + (void)"\nダイナミックリンクファンクションのロードを開始します\n"; + } + + if (gOverlayLogSeverity >= 3) { + // "DMA transfer of TEXT, DATA, RODATA + rel (%08x-%08x)" + (void)"TEXT,DATA,RODATA+relをDMA転送します(%08x-%08x)\n"; + } end = (void*)((uintptr_t)allocatedRamAddr + size); func_8007DF0C(allocatedRamAddr, vromStart, size); ovl = (OverlayRelocationSection*)((uintptr_t)end - ((s32*)end)[-1]); - if (gLoad2LogSeverity >= 3) {} - if (gLoad2LogSeverity >= 3) {} + if (gOverlayLogSeverity >= 3) { + (void)"TEXT(%08x), DATA(%08x), RODATA(%08x), BSS(%08x)\n"; + } + + if (gOverlayLogSeverity >= 3) { + // "Relocate" + (void)"リロケーションします\n"; + } DoRelocation(allocatedRamAddr, ovl, vramStart); if (ovl->bssSize != 0) { - if (gLoad2LogSeverity >= 3) {} + if (gOverlayLogSeverity >= 3) { + // "Clear BSS area (% 08x-% 08x)" + (void)"BSS領域をクリアします(%08x-%08x)\n"; + } bzero(end, ovl->bssSize); } @@ -150,16 +185,19 @@ size_t Load2_LoadOverlay(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramS osWritebackDCache(allocatedRamAddr, size); osInvalICache(allocatedRamAddr, size); - if (gLoad2LogSeverity >= 3) {} + if (gOverlayLogSeverity >= 3) { + // "Finish loading dynamic link function" + (void)"ダイナミックリンクファンクションのロードを終了します\n\n"; + } return size; } -void* Load2_AllocateAndLoad(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramStart, uintptr_t vramEnd) { +void* Overlay_AllocateAndLoad(uintptr_t vromStart, uintptr_t vromEnd, uintptr_t vramStart, uintptr_t vramEnd) { void* allocatedRamAddr = func_80064DD0(vramEnd - vramStart); if (allocatedRamAddr != NULL) { - Load2_LoadOverlay(vromStart, vromEnd, vramStart, vramEnd, allocatedRamAddr); + Overlay_Load(vromStart, vromEnd, vramStart, vramEnd, allocatedRamAddr); } return allocatedRamAddr; diff --git a/src/main/stackcheck.c b/src/main/stackcheck.c index 5318f9d..80f8a42 100644 --- a/src/main/stackcheck.c +++ b/src/main/stackcheck.c @@ -1,4 +1,5 @@ #include "stackcheck.h" +#include "terminal.h" #include "libc/stdbool.h" #include "libc/stdint.h" @@ -79,12 +80,19 @@ s32 StackCheck_Check(StackEntry* entry) { free = (uintptr_t)iter - (uintptr_t)entry->head; if (free == 0) { ret = STACK_STATUS_OVERFLOW; + (void)VT_FGCOL(RED); } else if ((free < entry->minSpace) && (entry->minSpace != -1)) { ret = STACK_STATUS_WARNING; + (void)VT_FGCOL(YELLOW); } else { + (void)VT_FGCOL(GREEN); ret = STACK_STATUS_OK; } + (void)"head=%08x tail=%08x last=%08x used=%08x free=%08x [%s]\n"; + (void)((entry->name) ? entry->name : "(null)"); + (void)VT_RST; + return ret; } } diff --git a/yamls/us/main.yaml b/yamls/us/main.yaml index 6b1f02a..b0c9467 100644 --- a/yamls/us/main.yaml +++ b/yamls/us/main.yaml @@ -237,7 +237,10 @@ - [0xAB7B0, data] # rodata: vram start 800ABBE0 - - [0xAC7E0, rodata] + - [0xAC7E0, rodata] + - [0xB3B70, .rodata, 80C50] + - [0xB3B80, .rodata, loadfragment2] + - [0xB3D20, .rodata, stackcheck] - [0xB3D80, .rodata, math64] # - [0xB3DA0, rodata] # # - [0xB58B0, .bss] # size = 0x5DFF0