Add memory typedefs

This commit is contained in:
Arceveti
2023-04-30 18:51:41 -04:00
parent 1806cfee21
commit 2ed18924a4
19 changed files with 160 additions and 146 deletions

View File

@@ -69,8 +69,19 @@ struct Controller {
#endif
};
// -- Booleans --
// -- Memory --
typedef u8 Byte;
typedef u16 Halfword;
typedef u32 Word;
typedef u64 Doubleword;
typedef uintptr_t Address; //! TODO: 64 bit addressing mode.
typedef u64 Register; //! TODO: 32 bit mode.
// -- String --
typedef unsigned char* String;
// -- Booleans --
typedef u8 Bool8;
typedef u16 Bool16;
typedef u32 Bool32;

View File

@@ -8,7 +8,7 @@
_Bool gAddressSelectMenuOpen = FALSE;
static uintptr_t sAddressSelectTarget = 0x00000000;
static Address sAddressSelectTarget = 0x00000000;
static s8 sAddressSelecCharIndex = 2;
@@ -43,7 +43,7 @@ void draw_address_select(void) {
crash_screen_print((SCREEN_CENTER_X - TEXT_WIDTH(8 / 2) - TEXT_WIDTH(2)), (JUMP_MENU_Y1 + TEXT_HEIGHT(2)), (STR_HEX_PREFIX STR_HEX_WORD), sAddressSelectTarget);
#ifdef INCLUDE_DEBUG_MAP
uintptr_t checkAddr = sAddressSelectTarget;
Address checkAddr = sAddressSelectTarget;
const char* fname = parse_map(&checkAddr);
if (fname != NULL) {
// "[function name]"
@@ -62,10 +62,10 @@ void crash_screen_select_address(void) {
sAddressSelecCharIndex = ((sAddressSelecCharIndex + 1) & 0x7); // % 8
}
uintptr_t nextSelectedAddress = sAddressSelectTarget;
Address nextSelectedAddress = sAddressSelectTarget;
u32 shift = ((32 - 4) - (sAddressSelecCharIndex * 4));
u8 digit = GET_HEX_DIGIT(sAddressSelectTarget, shift);
s8 new = digit;
u8 new = digit;
if (gCSDirectionFlags.pressed.up) {
// Increment the selected digit.
@@ -129,7 +129,7 @@ void crash_screen_select_address(void) {
}
// Open the jump to address popup.
void open_address_select(uintptr_t dest) {
void open_address_select(Address dest) {
gAddressSelectMenuOpen = TRUE;
sAddressSelectTarget = dest;
}

View File

@@ -31,4 +31,4 @@ extern _Bool gAddressSelectMenuOpen;
void draw_address_select(void);
void crash_screen_select_address(void);
void open_address_select(uintptr_t dest);
void open_address_select(Address dest);

View File

@@ -29,9 +29,9 @@ static _Bool glyph_to_hex(char* dest, unsigned char glyph) {
return TRUE;
}
static _Bool read_str_to_bytes(u8 dest[], const char* buf, u32 index, size_t numBytes) {
static _Bool read_str_to_bytes(Byte dest[], const char* buf, u32 index, size_t numBytes) {
for (u32 byteIndex = 0; byteIndex < numBytes; byteIndex++) {
u8 retByte = 0x00;
Byte retByte = 0x00;
for (int digit = 0; digit < 2; digit++) {
unsigned char glyph = buf[index];
@@ -57,10 +57,10 @@ static _Bool read_str_to_bytes(u8 dest[], const char* buf, u32 index, size_t num
static _Bool is_special_char(unsigned char glyph) {
return (
glyph == CHAR_ESCAPE ||
glyph == CHAR_NEWLINE ||
glyph == CHAR_RETURN ||
glyph == CHAR_COLOR
(glyph == CHAR_ESCAPE ) ||
(glyph == CHAR_NEWLINE) ||
(glyph == CHAR_RETURN ) ||
(glyph == CHAR_COLOR )
);
}
@@ -135,10 +135,10 @@ static u32 get_next_word_length(PrintBuffer* buf, u32 index, size_t size) {
while (index < size) {
unsigned char glyph = buf[index].glyph;
if (
glyph == CHAR_NULL ||
glyph == CHAR_SPACE ||
glyph == CHAR_NEWLINE ||
glyph == CHAR_RETURN
(glyph == CHAR_NULL ) ||
(glyph == CHAR_SPACE ) ||
(glyph == CHAR_NEWLINE) ||
(glyph == CHAR_RETURN )
) {
break;
}

View File

@@ -48,8 +48,8 @@ static _Bool sFirstCrash = TRUE;
struct CSThreadInfo* gActiveCSThreadInfo = NULL;
OSThread* gCrashedThread = NULL;
uintptr_t gCrashAddress = 0x00000000; // Crashed thread PC.
uintptr_t gSelectedAddress = 0x00000000; // Selected address for ram viewer and disasm pages.
Address gCrashAddress = 0x00000000; // Crashed thread PC.
Address gSelectedAddress = 0x00000000; // Selected address for ram viewer and disasm pages.
void crash_screen_reinitialize(void) {

View File

@@ -10,15 +10,14 @@
#include "crash_print.h"
#include "insn_disasm.h"
#include "map_parser.h"
#include "address_select.h"
enum CrashScreenMessageIDs {
CRASH_SCREEN_MSG_NONE,
CRASH_SCREEN_MSG_CPU_BREAK,
CRASH_SCREEN_MSG_SP_BREAK,
CRASH_SCREEN_MSG_FAULT,
CRASH_SCREEN_MSG_VI_VBLANK,
CRASH_SCREEN_MSG_CPU_BREAK = OS_EVENT_CPU_BREAK,
CRASH_SCREEN_MSG_SP_BREAK = OS_EVENT_SP_BREAK ,
CRASH_SCREEN_MSG_FAULT = OS_EVENT_FAULT ,
};
enum CrashScreenPages {
@@ -42,8 +41,8 @@ extern enum CrashScreenPages gCSPageID;
extern struct CSThreadInfo* gActiveCSThreadInfo;
extern OSThread* gCrashedThread;
extern uintptr_t gCrashAddress;
extern uintptr_t gSelectedAddress;
extern Address gCrashAddress;
extern Address gSelectedAddress;
void create_crash_screen_thread(void);

View File

@@ -15,12 +15,13 @@ typedef u32 CSFontRow;
#define VALID_RAM_END RAM_END
#define VALID_RAM_SIZE (u64)(VALID_RAM_END - VALID_RAM_START)
#define NUM_CRASH_SCREEN_BUFFERS 3
struct CSThreadInfo {
/*0x000*/ OSThread thread; /*0x1B0*/
/*0x1B0*/ u64 stack[THREAD2_STACK / sizeof(u64)]; /*0x400*/
/*0x1B0*/ Register stack[THREAD2_STACK / sizeof(Register)]; /*0x400*/
/*0x4B0*/ OSMesgQueue mesgQueue; /*0x18*/
/*0x4C8*/ OSMesg mesg; /*0x04*/
}; /*0x4CC*/
@@ -42,9 +43,9 @@ struct CSPage {
// Time conversion macros
#define FPS_COUNT 30
#define FRAMES_TO_NESC(f) (((u64)(f) * 1000000000LL) / FPS_COUNT)
#define FRAMES_TO_UESC(f) (((u64)(f) * 1000000LL) / FPS_COUNT)
#define FRAMES_TO_CYCLES(f) (((u64)(f) * OS_CPU_COUNTER) / FPS_COUNT)
#define NSEC_TO_FRAMES(n) (((u64)(n) * FPS_COUNT) / 1000000000LL)
#define USEC_TO_FRAMES(n) (((u64)(n) * FPS_COUNT) / 1000000LL)
#define CYCLES_TO_FRAMES(c) (((u64)(c) * FPS_COUNT) / OS_CPU_COUNTER)
#define FRAMES_TO_NESC(f) (((OSTime)(f) * 1000000000LL) / FPS_COUNT)
#define FRAMES_TO_UESC(f) (((OSTime)(f) * 1000000LL) / FPS_COUNT)
#define FRAMES_TO_CYCLES(f) (((OSTime)(f) * OS_CPU_COUNTER) / FPS_COUNT)
#define NSEC_TO_FRAMES(n) (((OSTime)(n) * FPS_COUNT) / 1000000000LL)
#define USEC_TO_FRAMES(n) (((OSTime)(n) * FPS_COUNT) / 1000000LL)
#define CYCLES_TO_FRAMES(c) (((OSTime)(c) * FPS_COUNT) / OS_CPU_COUNTER)

View File

@@ -12,7 +12,7 @@
/**
* How to find instructions:
*
*
* - If first 4 bits (cop_opcode) == 0100 (COP_OPCODE):
* - The next 2 bits (cop_num) are coprocessor number, so use insn_db_cop(z)
* - If the next bit (cop_bit) is set:
@@ -331,7 +331,7 @@ static _Bool check_pseudo_instructions(const InsnTemplate** type, InsnData insn)
static enum InsnType get_insn_type_and_list(InsnData insn, const InsnTemplate** checkInsn) {
enum InsnType insnType = INSN_TYPE_OPCODE;
*checkInsn = insn_db;
if (insn.cop_opcode == COP_OPCODE) { // COPz
if (insn.cop_num < ARRAY_COUNT(insn_db_cop_lists)) {
*checkInsn = insn_db_cop_lists[insn.cop_num];
@@ -466,21 +466,21 @@ s16 check_for_branch_offset(InsnData insn) {
return 0x0000;
}
uintptr_t get_branch_target_from_addr(uintptr_t addr) {
Address get_branch_target_from_addr(Address addr) {
if (!is_in_code_segment(addr)) {
return addr;
}
InsnData insn = { .raw = *(uintptr_t*)addr };
InsnData insn = { .raw = *(Word*)addr };
if (insn.opcode == OPC_J || insn.opcode == OPC_JAL) {
return PHYSICAL_TO_VIRTUAL(insn.instr_index * sizeof(uintptr_t));
return PHYSICAL_TO_VIRTUAL(insn.instr_index * sizeof(InsnData));
}
s16 branchOffset = check_for_branch_offset(insn);
if (branchOffset) {
return (addr + (((s16)branchOffset + 1) * sizeof(uintptr_t)));
return (addr + (((s16)branchOffset + 1) * sizeof(InsnData)));
}
return addr;
@@ -515,12 +515,12 @@ static char insn_name[INSN_NAME_DISPLAY_WIDTH] = "";
#define STR_INSN_NAME "%-"TO_STRING2(INSN_NAME_DISPLAY_WIDTH)"s"
#define STR_INSN_NAME_FORMAT STR_INSN_NAME_BASE"."STR_FORMAT
#define STR_IREG "%s" // Register
#define STR_IMMEDIATE STR_HEX_PREFIX STR_HEX_HALFWORD // 0xI
#define STR_OFFSET "%c"STR_IMMEDIATE // ±Offset
#define STR_FUNCTION STR_HEX_PREFIX STR_HEX_WORD // Function address
#define STR_IREG_BASE "("STR_IREG")" // Base register
#define STR_FREG "F%02d" // Float Register
#define STR_IREG "%s" // Register
#define STR_IMMEDIATE STR_HEX_PREFIX STR_HEX_HALFWORD // 0xI
#define STR_OFFSET "%c"STR_IMMEDIATE // ±Offset
#define STR_FUNCTION STR_HEX_PREFIX STR_HEX_WORD // Function address
#define STR_IREG_BASE "("STR_IREG")" // Base register
#define STR_FREG "F%02d" // Float Register
char* insn_disasm(InsnData insn, const char** fname, _Bool showDestNames) {
char* strp = &insn_as_string[0];
@@ -619,10 +619,10 @@ char* insn_disasm(InsnData insn, const char** fname, _Bool showDestNames) {
break;
case CHAR_P_FUNC:
check_color_change(&strp, &color, COLOR_RGBA32_CRASH_FUNCTION_NAME);
uintptr_t target = PHYSICAL_TO_VIRTUAL(insn.instr_index * sizeof(uintptr_t));
Address target = PHYSICAL_TO_VIRTUAL(insn.instr_index * sizeof(InsnData));
#ifdef INCLUDE_DEBUG_MAP
if (showDestNames && is_in_code_segment(target)) {
uintptr_t tempTarget = target;
Address tempTarget = target;
*fname = parse_map(&tempTarget);
// Only print as the function name if it's the exact starting address of the function.
if (target != tempTarget) {

View File

@@ -434,5 +434,5 @@ typedef struct PACKED {
s16 check_for_branch_offset(InsnData insn);
uintptr_t get_branch_target_from_addr(uintptr_t addr);
Address get_branch_target_from_addr(Address addr);
char* insn_disasm(InsnData insn, const char** fname, _Bool showDestNames);

View File

@@ -48,11 +48,11 @@ TEXT_REGION_GROUP(common1)
size_t gNumMapEntries = 0;
static void headless_dma(uintptr_t devAddr, void* dramAddr, size_t size) {
static void headless_dma(Address devAddr, void* dramAddr, size_t size) {
while (IO_READ(PI_STATUS_REG) & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY));
IO_WRITE(PI_DRAM_ADDR_REG, K0_TO_PHYS(dramAddr));
IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS((uintptr_t)osRomBase | devAddr));
IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS((Address)osRomBase | devAddr));
IO_WRITE(PI_WR_LEN_REG, (size - 1));
while (IO_READ(PI_STATUS_REG) & (PI_STATUS_DMA_BUSY | PI_STATUS_ERROR));
@@ -61,15 +61,15 @@ static void headless_dma(uintptr_t devAddr, void* dramAddr, size_t size) {
void map_data_init(void) {
gNumMapEntries = (gMapEntryEnd - gMapEntries);
uintptr_t start = (uintptr_t)_mapDataSegmentRomStart;
uintptr_t end = (uintptr_t)_mapDataSegmentRomEnd;
Address start = (Address)_mapDataSegmentRomStart;
Address end = (Address)_mapDataSegmentRomEnd;
headless_dma((uintptr_t)_mapDataSegmentRomStart, (size_t*)(RAM_END - RAM_1MB), (end - start));
headless_dma((Address)_mapDataSegmentRomStart, (size_t*)(RAM_END - RAM_1MB), (end - start));
}
// Check whether the address is in a .text segment.
//! TODO: do INCLUDE_DEBUG_MAP inside this instead of on this whole file.
_Bool is_in_code_segment(uintptr_t addr) {
_Bool is_in_code_segment(Address addr) {
//! TODO: Allow reading .text memory outside 0x80000000-0x80800000.
if (!IS_IN_RDRAM(addr)) {
return FALSE;
@@ -85,16 +85,17 @@ _Bool is_in_code_segment(uintptr_t addr) {
}
const char* get_map_entry_name(const struct MapEntry* entry) {
return (const char*)((uintptr_t)gMapStrings + entry->name_offset);
return (const char*)((u32)gMapStrings + entry->name_offset);
}
s32 get_map_entry_index(uintptr_t addr) {
s32 get_map_entry_index(Address addr) {
const struct MapEntry* entry = &gMapEntries[0];
for (size_t i = 0; i < gNumMapEntries; i++) {
if ((addr >= entry->addr) && (addr < (entry->addr + entry->size))) {
return i;
}
entry++;
}
@@ -102,11 +103,11 @@ s32 get_map_entry_index(uintptr_t addr) {
}
// Changes 'addr' to the starting address of the function it's in and returns a pointer to the function name.
const char* parse_map(uintptr_t* addr) {
const char* parse_map(Address* addr) {
#ifndef INCLUDE_DEBUG_MAP
return NULL;
#endif
*addr = ALIGNFLOOR(*addr, sizeof(uintptr_t));
*addr = ALIGNFLOOR(*addr, sizeof(Word));
if (!is_in_code_segment(*addr)) {
return NULL;
@@ -124,20 +125,20 @@ const char* parse_map(uintptr_t* addr) {
}
// Check whether two addresses share the same function.
_Bool is_in_same_function(uintptr_t oldPos, uintptr_t newPos) {
if (oldPos == newPos) {
_Bool is_in_same_function(Address addr1, Address addr2) {
if (addr1 == addr2) {
return TRUE;
}
oldPos = ALIGNFLOOR(oldPos, sizeof(uintptr_t));
newPos = ALIGNFLOOR(newPos, sizeof(uintptr_t));
addr1 = ALIGNFLOOR(addr1, sizeof(Word));
addr2 = ALIGNFLOOR(addr2, sizeof(Word));
if (oldPos == newPos) {
if (addr1 == addr2) {
return TRUE;
}
parse_map(&oldPos);
parse_map(&newPos);
parse_map(&addr1);
parse_map(&addr2);
return (oldPos == newPos);
return (addr1 == addr2);
}

View File

@@ -6,19 +6,19 @@
struct MapEntry {
/*0x00*/ uintptr_t addr;
/*0x00*/ Address addr;
/*0x04*/ size_t size;
/*0x08*/ uintptr_t name_offset;
/*0x08*/ size_t name_offset;
/*0x0C*/ size_t name_len;
}; /*0x10*/
typedef struct {
/*0x00*/ const uintptr_t start;
/*0x04*/ const uintptr_t end;
/*0x00*/ const Address start;
/*0x04*/ const Address end;
} MemoryRegion; /*0x08*/
#define EXTERN_TEXT_SYMBOL(name, side) \
extern const u8 _##name##SegmentText##side[];
extern const Byte _##name##SegmentText##side[];
#define EXTERN_TEXT_REGION(name) \
EXTERN_TEXT_SYMBOL(name, Start) \
@@ -73,7 +73,7 @@ EXTERN_GROUP_TEXT(common1)
#undef DEFINE_LEVEL
#define MEMORY_REGION(start, end) \
{ (const uintptr_t)(start), (const uintptr_t)(end) },
{ (const Address)(start), (const Address)(end) },
#define TEXT_REGION(name) \
MEMORY_REGION(_##name##SegmentTextStart, _##name##SegmentTextEnd)
@@ -94,18 +94,18 @@ EXTERN_GROUP_TEXT(common1)
extern const struct MapEntry gMapEntries[];
extern const struct MapEntry gMapEntryEnd[];
extern const u8 gMapStrings[];
extern const u8 gMapStringEnd[];
extern const u8 _mapDataSegmentRomStart[];
extern const u8 _mapDataSegmentRomEnd[];
extern const Byte gMapStrings[];
extern const Byte gMapStringEnd[];
extern const Byte _mapDataSegmentRomStart[];
extern const Byte _mapDataSegmentRomEnd[];
extern size_t gNumMapEntries;
void map_data_init(void);
_Bool is_in_code_segment(uintptr_t addr);
_Bool is_in_code_segment(Address addr);
const char* get_map_entry_name(const struct MapEntry* entry);
s32 get_map_entry_index(uintptr_t addr);
const char* parse_map(uintptr_t* addr);
_Bool is_in_same_function(uintptr_t oldPos, uintptr_t newPos);
s32 get_map_entry_index(Address addr);
const char* parse_map(Address* addr);
_Bool is_in_same_function(Address addr1, Address addr2);

View File

@@ -29,7 +29,7 @@ void assert_draw(void) { //! TODO: Make this scrollable if the message long enou
// "No failed assert to report."
crash_screen_print(TEXT_X(0), TEXT_Y(line), "No failed assert to report.");
}
gCSWordWrap = FALSE;
osWritebackDCacheAll();

View File

@@ -50,7 +50,7 @@ static const char* sRegNames[29] = { //! TODO: Combine this with sCPURegisterNam
// Print a fixed-point register.
void crash_screen_print_reg(u32 x, u32 y, const char* name, uintptr_t addr) {
void crash_screen_print_reg(u32 x, u32 y, const char* name, Address addr) {
// "[register name]: [XXXXXXXX]"
crash_screen_print(x, y,
" "STR_COLOR_PREFIX"%s: "STR_COLOR_PREFIX STR_HEX_WORD,
@@ -62,14 +62,14 @@ void crash_screen_print_reg(u32 x, u32 y, const char* name, uintptr_t addr) {
// Print important fixed-point registers.
void crash_screen_print_registers(__OSThreadContext* tc) {
u32 regNum = 0;
u64* reg = &tc->at;
Register* reg = &tc->at;
crash_screen_print_reg(TEXT_X(0 * 15), TEXT_Y( 3), "PC", tc->pc);
crash_screen_print_reg(TEXT_X(1 * 15), TEXT_Y( 3), "SR", tc->sr);
crash_screen_print_reg(TEXT_X(2 * 15), TEXT_Y( 3), "VA", tc->badvaddr);
crash_screen_print_reg(TEXT_X(0 * 15), TEXT_Y(3), "PC", tc->pc);
crash_screen_print_reg(TEXT_X(1 * 15), TEXT_Y(3), "SR", tc->sr);
crash_screen_print_reg(TEXT_X(2 * 15), TEXT_Y(3), "VA", tc->badvaddr);
if (IS_IN_RDRAM(tc->pc)) {
crash_screen_print_reg(TEXT_X(2 * 15), TEXT_Y(13), "MM", *(uintptr_t*)tc->pc); // The raw data of the asm code that crashed.
crash_screen_print_reg(TEXT_X(2 * 15), TEXT_Y(13), "MM", *(Word*)tc->pc); // The raw data of the asm code that crashed.
}
osWritebackDCacheAll();
@@ -110,12 +110,12 @@ void crash_screen_print_fpcsr(u32 x, u32 y, u32 fpcsr) {
}
// Print a floating-point register.
void crash_screen_print_float_reg(u32 x, u32 y, u32 regNum, f32* addr) {
void crash_screen_print_float_reg(u32 x, u32 y, u32 regNum, f32* data) {
// "[register name]:"
size_t charX = crash_screen_print(x, y, STR_COLOR_PREFIX"F%02d:", COLOR_RGBA32_CRASH_REGISTER, regNum);
x += TEXT_WIDTH(charX);
IEEE754_f32 val = { .asF32 = *addr };
IEEE754_f32 val = { .asF32 = *data };
char prefix = '\0';
@@ -161,7 +161,7 @@ void crash_screen_print_float_registers(__OSThreadContext* tc) {
void crash_context_draw(void) {
__OSThreadContext* tc = &gCrashedThread->context;
s32 cause = ((tc->cause >> CAUSE_EXCSHIFT) & BITMASK(5));
u32 cause = ((tc->cause >> CAUSE_EXCSHIFT) & BITMASK(5));
// Make the last two cause case indexes sequential for array access.
if (cause == (EXC_WATCH >> CAUSE_EXCSHIFT)) cause = 16;
if (cause == (EXC_VCED >> CAUSE_EXCSHIFT)) cause = 17;
@@ -180,11 +180,11 @@ void crash_context_draw(void) {
osWritebackDCacheAll();
#ifdef INCLUDE_DEBUG_MAP
uintptr_t pc = tc->pc;
Address pc = tc->pc;
const char* fname = parse_map(&pc);
// "CRASH AT:"
// "CRASH IN:"
size_t charX = crash_screen_print(TEXT_X(0), TEXT_Y(line),
STR_COLOR_PREFIX"CRASH AT: ",
STR_COLOR_PREFIX"CRASH IN: ",
COLOR_RGBA32_CRASH_AT
);
if (fname == NULL) {

View File

@@ -30,10 +30,10 @@ static _Bool sContinueFillBranchBuffer = FALSE;
ALIGNED16 static struct BranchArrow sBranchArrows[DISASM_BRANCH_BUFFER_SIZE];
static u32 sNumBranchArrows = 0;
static uintptr_t sBranchBufferCurrAddr = 0x00000000;
static Address sBranchBufferCurrAddr = 0x00000000;
void reset_branch_buffer(uintptr_t funcAddr) {
void reset_branch_buffer(Address funcAddr) {
bzero(sBranchArrows, sizeof(sBranchArrows));
sNumBranchArrows = 0;
@@ -42,7 +42,7 @@ void reset_branch_buffer(uintptr_t funcAddr) {
//! TODO: Optimize this as much as possible
//! TODO: Version that works without INCLUDE_DEBUG_MAP (check for branches relative to viewport)
_Bool crash_screen_fill_branch_buffer(const char* fname, uintptr_t funcAddr) {
_Bool crash_screen_fill_branch_buffer(const char* fname, Address funcAddr) {
if (fname == NULL) {
return FALSE;
}
@@ -60,6 +60,7 @@ _Bool crash_screen_fill_branch_buffer(const char* fname, uintptr_t funcAddr) {
curBranchX = sBranchArrows[sNumBranchArrows - 1].xPos;
}
// Pick up where we left off.
struct BranchArrow* currArrow = &sBranchArrows[sNumBranchArrows];
OSTime startTime = osGetTime();
@@ -75,7 +76,7 @@ _Bool crash_screen_fill_branch_buffer(const char* fname, uintptr_t funcAddr) {
}
// Left the function.
uintptr_t checkAddr = sBranchBufferCurrAddr;
Address checkAddr = sBranchBufferCurrAddr;
if (!is_in_code_segment(checkAddr)) {
return FALSE;
}
@@ -85,10 +86,10 @@ _Bool crash_screen_fill_branch_buffer(const char* fname, uintptr_t funcAddr) {
}
// Get the offset for the current function;
InsnData insn = (InsnData){ .raw = *(uintptr_t*)sBranchBufferCurrAddr };
InsnData insn = (InsnData){ .raw = *(Word*)sBranchBufferCurrAddr };
s16 branchOffset = check_for_branch_offset(insn);
if (branchOffset != 0) { //! TODO: Verify ordering:
if (branchOffset != 0x0000) { //! TODO: Verify ordering:
curBranchX += DISASM_BRANCH_ARROW_SPACING;
curBranchColorIndex = ((curBranchColorIndex + 1) % ARRAY_COUNT(sBranchColors));
@@ -125,7 +126,7 @@ void disasm_init(void) {
sDisasmShowDataAsBinary = FALSE;
gFillBranchBuffer = FALSE;
sContinueFillBranchBuffer = FALSE;
reset_branch_buffer((uintptr_t)NULL);
reset_branch_buffer((Address)NULL);
}
void draw_branch_arrow(s32 startLine, s32 endLine, s32 dist, RGBA32 color, u32 printLine) {
@@ -180,7 +181,7 @@ void disasm_draw_branch_arrows(u32 printLine) {
osWritebackDCacheAll();
}
static void print_as_insn(const u32 charX, const u32 charY, const uintptr_t data) {
static void print_as_insn(const u32 charX, const u32 charY, const Word data) {
InsnData insn = { .raw = data };
#ifndef INCLUDE_DEBUG_MAP
s16 branchOffset = check_for_branch_offset(insn);
@@ -197,7 +198,8 @@ static void print_as_insn(const u32 charX, const u32 charY, const uintptr_t data
#ifdef INCLUDE_DEBUG_MAP
if (sDisasmShowDestFunctionNames && destFname != NULL) {
// "[function name]"
crash_screen_print_scroll((charX + TEXT_WIDTH(INSN_NAME_DISPLAY_WIDTH)), charY, (CRASH_SCREEN_NUM_CHARS_X - (INSN_NAME_DISPLAY_WIDTH)),
crash_screen_print_scroll((charX + TEXT_WIDTH(INSN_NAME_DISPLAY_WIDTH)), charY,
(CRASH_SCREEN_NUM_CHARS_X - (INSN_NAME_DISPLAY_WIDTH)),
STR_COLOR_PREFIX"%s",
COLOR_RGBA32_CRASH_FUNCTION_NAME, destFname
);
@@ -205,7 +207,7 @@ static void print_as_insn(const u32 charX, const u32 charY, const uintptr_t data
#endif
}
static void print_as_binary(const u32 charX, const u32 charY, const uintptr_t data) { //! TODO: make this a formatting char, maybe \%b?
static void print_as_binary(const u32 charX, const u32 charY, const Word data) { //! TODO: make this a formatting char?, maybe \%b?
u32 bitX = charX;
for (u32 c = 0; c < 32; c++) {
@@ -219,14 +221,14 @@ static void print_as_binary(const u32 charX, const u32 charY, const uintptr_t da
}
}
void disasm_draw_asm_entries(u32 line, u32 numLines, uintptr_t selectedAddr, uintptr_t pc) {
static void disasm_draw_asm_entries(u32 line, u32 numLines, Address selectedAddr, Address pc) {
u32 charX = TEXT_X(0);
u32 charY = TEXT_Y(line);
sDisasmViewportIndex = clamp_view_to_selection(sDisasmViewportIndex, gSelectedAddress, numLines, DISASM_STEP);
for (u32 y = 0; y < numLines; y++) {
uintptr_t addr = (sDisasmViewportIndex + (y * DISASM_STEP));
Address addr = (sDisasmViewportIndex + (y * DISASM_STEP));
charY = TEXT_Y(line + y);
// Draw crash and selection rectangles:
@@ -240,7 +242,7 @@ void disasm_draw_asm_entries(u32 line, u32 numLines, uintptr_t selectedAddr, uin
crash_screen_draw_rect((charX - 1), (charY - 2), (CRASH_SCREEN_TEXT_W + 1), (TEXT_HEIGHT(1) + 1), COLOR_RGBA32_CRASH_SELECT);
}
uintptr_t data = *(uintptr_t*)addr;
Word data = *(Word*)addr;
if (is_in_code_segment(addr)) {
print_as_insn(charX, charY, data);
@@ -258,16 +260,16 @@ void disasm_draw_asm_entries(u32 line, u32 numLines, uintptr_t selectedAddr, uin
osWritebackDCacheAll();
}
//! TODO: automatically check page change:
// uintptr_t sCurrFuncAddr = 0x00000000;
//! TODO: automatically check page/address change:
// Address sCurrFuncAddr = 0x00000000;
// const char* sCurrFuncName = NULL;
void disasm_draw(void) {
__OSThreadContext* tc = &gCrashedThread->context;
const char* fname = NULL;
uintptr_t alignedSelectedAddr = ALIGNFLOOR(gSelectedAddress, DISASM_STEP);
Address alignedSelectedAddr = ALIGNFLOOR(gSelectedAddress, DISASM_STEP);
#ifdef INCLUDE_DEBUG_MAP
uintptr_t funcAddr = alignedSelectedAddr;
Address funcAddr = alignedSelectedAddr;
fname = parse_map(&funcAddr);
#endif
@@ -330,7 +332,7 @@ const enum ControlTypes disasmContList[] = {
void disasm_input(void) {
#ifdef INCLUDE_DEBUG_MAP
uintptr_t oldPos = gSelectedAddress;
Address oldPos = gSelectedAddress;
#endif
if (gCSDirectionFlags.pressed.up) {
@@ -361,11 +363,12 @@ void disasm_input(void) {
}
#ifdef INCLUDE_DEBUG_MAP
//! TODO: don't reset branch buffer if switched page back into the same function.
if (gCSSwitchedPage || !is_in_same_function(oldPos, gSelectedAddress)) {
gFillBranchBuffer = TRUE;
}
uintptr_t funcAddr = ALIGNFLOOR(gSelectedAddress, DISASM_STEP);
Address funcAddr = ALIGNFLOOR(gSelectedAddress, DISASM_STEP);
const char* fname = parse_map(&funcAddr);
if (gFillBranchBuffer) {

View File

@@ -6,7 +6,7 @@
struct BranchArrow {
/*0x00*/ uintptr_t startAddr;
/*0x00*/ Address startAddr;
/*0x02*/ s16 branchOffset;
/*0x04*/ s16 colorIndex;
/*0x08*/ s32 xPos;

View File

@@ -7,11 +7,22 @@
#include "game/game_input.h"
static u32 sRamViewViewportIndex = 0x00000000;
static Address sRamViewViewportIndex = 0x00000000;
static _Bool sRamViewShowAsAscii = FALSE;
const enum ControlTypes ramViewerContList[] = {
CONT_DESC_SWITCH_PAGE,
CONT_DESC_SHOW_CONTROLS,
CONT_DESC_CYCLE_DRAW,
CONT_DESC_CURSOR,
CONT_DESC_JUMP_TO_ADDRESS,
CONT_DESC_TOGGLE_ASCII,
CONT_DESC_LIST_END,
};
void ram_viewer_init(void) {
sRamViewViewportIndex = gSelectedAddress;
sRamViewShowAsAscii = FALSE;
@@ -19,7 +30,7 @@ void ram_viewer_init(void) {
static const char gHex[0x10] = "0123456789ABCDEF";
static void print_byte(u32 x, u32 y, u8 byte, RGBA32 color) {
static void print_byte(u32 x, u32 y, Byte byte, RGBA32 color) {
// "XX"
if (sRamViewShowAsAscii) {
crash_screen_draw_glyph((x + TEXT_WIDTH(1)), y, byte, color);
@@ -35,8 +46,7 @@ void ram_viewer_draw(void) {
sRamViewViewportIndex = clamp_view_to_selection(sRamViewViewportIndex, gSelectedAddress, RAM_VIEWER_NUM_ROWS, RAM_VIEWER_STEP);
uintptr_t startAddr = sRamViewViewportIndex;
u32 charX, charY;
Address startAddr = sRamViewViewportIndex;
u32 line = 1;
// "[XXXXXXXX] in [XXXXXXXX]-[XXXXXXXX]"
@@ -47,8 +57,9 @@ void ram_viewer_draw(void) {
line++;
charX = (TEXT_X(8) + 3);
u32 charX = (TEXT_X(8) + 3);
// Print column headers:
for (u32 i = 0; i < 16; i++) {
if ((i % 4) == 0) {
charX += 2;
@@ -70,10 +81,10 @@ void ram_viewer_draw(void) {
line++;
charX = (TEXT_X(8) + 3);
charY = TEXT_Y(line);
u32 charY = TEXT_Y(line);
for (u32 y = 0; y < RAM_VIEWER_NUM_ROWS; y++) {
uintptr_t rowAddr = (startAddr + (y * RAM_VIEWER_STEP));
Address rowAddr = (startAddr + (y * RAM_VIEWER_STEP));
// "[XXXXXXXX]"
crash_screen_print(TEXT_X(0), TEXT_Y(line + y), (STR_COLOR_PREFIX STR_HEX_WORD),
@@ -83,7 +94,7 @@ void ram_viewer_draw(void) {
charX = (TEXT_X(8) + 3);
charY = TEXT_Y(line + y);
for (u32 x = 0; x < 16; x++) {
uintptr_t currAddr = (rowAddr + x);
Address currAddr = (rowAddr + x);
if ((x % 4) == 0) {
charX += 2;
@@ -103,7 +114,7 @@ void ram_viewer_draw(void) {
crash_screen_draw_rect((charX - 1), (charY - 1), (TEXT_WIDTH(2) + 1), (TEXT_WIDTH(1) + 3), selectColor);
}
print_byte(charX, charY, *(vu8*)currAddr, textColor);
print_byte(charX, charY, *(Byte*)currAddr, textColor);
charX += (TEXT_WIDTH(2) + 1);
}
@@ -119,18 +130,6 @@ void ram_viewer_draw(void) {
osWritebackDCacheAll();
}
const enum ControlTypes ramViewerContList[] = {
CONT_DESC_SWITCH_PAGE,
CONT_DESC_SHOW_CONTROLS,
CONT_DESC_CYCLE_DRAW,
CONT_DESC_CURSOR,
CONT_DESC_JUMP_TO_ADDRESS,
CONT_DESC_TOGGLE_ASCII,
CONT_DESC_LIST_END,
};
void ram_viewer_input(void) {
if (gCSDirectionFlags.pressed.up) {
// Scroll up.
@@ -147,14 +146,14 @@ void ram_viewer_input(void) {
}
if (gCSDirectionFlags.pressed.left) {
// Don't wrap.
// Prevent wrapping.
if (((gSelectedAddress - 1) & BITMASK(4)) != 0xF) {
gSelectedAddress--;
}
}
if (gCSDirectionFlags.pressed.right) {
// Don't wrap.
// Prevent wrapping.
if (((gSelectedAddress + 1) & BITMASK(4)) != 0x0) {
gSelectedAddress++;
}

View File

@@ -6,7 +6,7 @@
// RAM Viewer constants
#define RAM_VIEWER_STEP (s32)(4 * sizeof(uintptr_t))
#define RAM_VIEWER_STEP (s32)(4 * sizeof(Word))
#define RAM_VIEWER_NUM_ROWS 19
#define RAM_VIEWER_SHOWN_SECTION ((RAM_VIEWER_NUM_ROWS - 1) * RAM_VIEWER_STEP)

View File

@@ -37,11 +37,11 @@ void fill_function_stack_trace(void) {
.fname = NULL,
};
u64* sp = (u64*)(uintptr_t)tc->sp; // Stack pointer is already aligned, so get the lower bits.
Register* sp = (Register*)(Address)tc->sp; // Stack pointer is already aligned, so get the lower bits.
// Loop through the stack buffer and find all the addresses that point to a function.
while ((u8*)sp < _buffersSegmentBssEnd && sNumFoundFunctions < STACK_TRACE_BUFFER_SIZE) {
currInfo.curAddr = (uintptr_t)(*sp);
while ((Byte*)sp < _buffersSegmentBssEnd && sNumFoundFunctions < STACK_TRACE_BUFFER_SIZE) {
currInfo.curAddr = (Address)(*sp);
if (is_in_code_segment(currInfo.curAddr)) {
currInfo.faddr = currInfo.curAddr;
@@ -49,11 +49,11 @@ void fill_function_stack_trace(void) {
if (currInfo.fname != NULL) {
//! TODO: If JAL command uses a different function than the previous entry's faddr, replace it with the one in the JAL command?
//! TODO: handle duplicate entries caused by JALR RA, V0
currInfo.stackAddr = (uintptr_t)sp + sizeof(uintptr_t);
currInfo.stackAddr = (Address)sp + sizeof(Address);
sFunctionStack[sNumFoundFunctions++] = currInfo;
}
if (currInfo.faddr == (uintptr_t)__osCleanupThread) {
if (currInfo.faddr == (Address)__osCleanupThread) {
break;
}
}
@@ -149,13 +149,13 @@ void stack_trace_draw(void) {
u32 line = 1;
// "FROM: [XXXXXXXX]"
crash_screen_print(TEXT_X(12), TEXT_Y(line), "FROM "STR_HEX_WORD, (uintptr_t)tc->sp);
crash_screen_print(TEXT_X(12), TEXT_Y(line), "FROM "STR_HEX_WORD, (Address)tc->sp);
line++;
#ifdef INCLUDE_DEBUG_MAP
crash_screen_print(TEXT_X(0), TEXT_Y(line), STR_COLOR_PREFIX"CURRFUNC:", COLOR_RGBA32_CRASH_AT);
uintptr_t pc = tc->pc;
Address pc = tc->pc;
const char* fname = parse_map(&pc);
if (fname == NULL) {
// "UNKNOWN"

View File

@@ -13,9 +13,9 @@
struct FunctionInStack {
/*0x00*/ uintptr_t stackAddr;
/*0x04*/ uintptr_t curAddr;
/*0x08*/ uintptr_t faddr;
/*0x00*/ Address stackAddr;
/*0x04*/ Address curAddr;
/*0x08*/ Address faddr;
/*0x0C*/ const char* fname;
}; /*0x10*/