From f54a8fc3f0017bb1f0be25464e105b314c8becc0 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 7 Oct 2021 21:23:59 +1000 Subject: [PATCH] Disassemble getReturnAddress --- ld/libfiles.ntsc-beta.inc | 1 + src/lib/getra.s | 45 +++++++++++++++++++++++++++++++++++++++ src/lib/lib_0c000.c | 28 ------------------------ src/lib/lib_18680.s | 1 + 4 files changed, 47 insertions(+), 28 deletions(-) create mode 100644 src/lib/getra.s diff --git a/ld/libfiles.ntsc-beta.inc b/ld/libfiles.ntsc-beta.inc index df08ce17d..54356f2d2 100644 --- a/ld/libfiles.ntsc-beta.inc +++ b/ld/libfiles.ntsc-beta.inc @@ -34,6 +34,7 @@ build/ROMID/lib/lib_09a80.o (section); \ build/ROMID/lib/lib_0bfb0.o (section); \ build/ROMID/lib/lib_0c000.o (section); \ + build/ROMID/lib/getra.o (section); \ build/ROMID/lib/dma.o (section); \ build/ROMID/lib/main.o (section); \ build/ROMID/lib/snd.o (section); \ diff --git a/src/lib/getra.s b/src/lib/getra.s new file mode 100644 index 000000000..a8d1c2b2b --- /dev/null +++ b/src/lib/getra.s @@ -0,0 +1,45 @@ +#include "macros.h" +.set noat +.set noreorder + +/** + * Get the return address ($ra) that the caller would return to. + * + * For example, a C function could use: + * + * osSyncPrintf("Called from %u\n", getReturnAddress()); + * + * It follows the current $ra to get to the function that called + * getReturnAddress, then steps backwards through that function's bytecode until + * it finds either `addiu $sp` or `sw $ra, 0xnn($sp)`. + * + * If it finds `addiu $sp` first then it's reached the top of the function and + * $ra wasn't saved to the stack. In this case something is massively wrong and + * the function returns -1. + * + * If it finds `sw $ra, 0xnn($sp)` first then it reads the stack offset out of + * the instruction, then reads the value out of the stack using that offset. + */ +glabel getReturnAddress + or $a0, $ra, $zero + addiu $v0, $zero, -1 +.loop: + lw $t0, 0($a0) + addiu $t2, $zero, 0x27bd + srl $t1, $t0, 16 + beq $t1, $t2, .foundtop + nop + dli $t2, 0xafbf + beql $t1, $t2, .foundstore + sll $t2, $t0, 16 + j .loop + addiu $a0, $a0, -4 + + sll $t2, $t0, 16 +.foundstore: + sra $t2, $t2, 16 + add $t2, $t2, $sp + lw $v0, 0($t2) +.foundtop: + jr $ra + nop diff --git a/src/lib/lib_0c000.c b/src/lib/lib_0c000.c index 955280ddb..4cd14a645 100644 --- a/src/lib/lib_0c000.c +++ b/src/lib/lib_0c000.c @@ -1546,31 +1546,3 @@ void func0000cf54(u16 *fb) } } } - -#if VERSION < VERSION_NTSC_1_0 -GLOBAL_ASM( -glabel func0000d678nb -/* d678: 00000000 */ sll $zero,$zero,0x0 -/* d67c: 00000000 */ sll $zero,$zero,0x0 -/* d680: 03e02025 */ or $a0,$ra,$zero -/* d684: 2402ffff */ addiu $v0,$zero,-1 -/* d688: 8c880000 */ lw $t0,0x0($a0) -/* d68c: 240a27bd */ addiu $t2,$zero,0x27bd -/* d690: 00084c02 */ srl $t1,$t0,0x10 -/* d694: 112a000a */ beq $t1,$t2,.NB0000d6c0 -/* d698: 00000000 */ sll $zero,$zero,0x0 -/* d69c: 340aafbf */ dli $t2,0xafbf -/* d6a0: 512a0004 */ beql $t1,$t2,.NB0000d6b4 -/* d6a4: 00085400 */ sll $t2,$t0,0x10 -/* d6a8: 080035a2 */ j 0xd688 -/* d6ac: 2484fffc */ addiu $a0,$a0,-4 -/* d6b0: 00085400 */ sll $t2,$t0,0x10 -.NB0000d6b4: -/* d6b4: 000a5403 */ sra $t2,$t2,0x10 -/* d6b8: 015d5020 */ add $t2,$t2,$sp -/* d6bc: 8d420000 */ lw $v0,0x0($t2) -.NB0000d6c0: -/* d6c0: 03e00008 */ jr $ra -/* d6c4: 00000000 */ sll $zero,$zero,0x0 -); -#endif diff --git a/src/lib/lib_18680.s b/src/lib/lib_18680.s index 291230189..1e1b9be00 100644 --- a/src/lib/lib_18680.s +++ b/src/lib/lib_18680.s @@ -1,3 +1,4 @@ +#include "versions.h" #include "macros.inc" .set noat .set noreorder