From 3aafbf3971502e70f9ff672c3c820137d8f1ce6f Mon Sep 17 00:00:00 2001 From: cadmic Date: Sun, 5 Jan 2025 22:45:12 -0800 Subject: [PATCH] Match remaining IDO files for iQue (#2394) --- Makefile | 27 +++++++++++++++++------ src/boot/driverominit.c | 7 ++++++ src/code/z_skelanime.c | 2 +- tools/disasm/ique-cn/files_boot.csv | 2 +- tools/patch_ique_driverominit.py | 34 +++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 9 deletions(-) create mode 100755 tools/patch_ique_driverominit.py diff --git a/Makefile b/Makefile index ae776fb033..d28ee42a6c 100644 --- a/Makefile +++ b/Makefile @@ -293,6 +293,9 @@ OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump NM := $(MIPS_BINUTILS_PREFIX)nm STRIP := $(MIPS_BINUTILS_PREFIX)strip +# Command to patch certain object files after they are built +POSTPROCESS_OBJ := @: + # The default iconv on macOS has some differences from GNU iconv, so we use the Homebrew version instead ifeq ($(UNAME_S),Darwin) ICONV := $(shell brew --prefix)/opt/libiconv/bin/iconv @@ -545,6 +548,15 @@ endif ifeq ($(COMPILER),ido) $(BUILD_DIR)/src/boot/driverominit.o: OPTFLAGS := -O2 +ifeq ($(PLATFORM),IQUE) +# iQue's driverominit.o seems to have been patched manually. For non-matching builds we edit the source code instead. +ifneq ($(NON_MATCHING),1) +$(BUILD_DIR)/src/boot/driverominit.o: POSTPROCESS_OBJ := $(PYTHON) tools/patch_ique_driverominit.py +endif + +$(BUILD_DIR)/src/boot/viconfig.o: OPTFLAGS := -O2 +endif + $(BUILD_DIR)/src/code/jpegutils.o: OPTFLAGS := -O2 $(BUILD_DIR)/src/code/jpegdecoder.o: OPTFLAGS := -O2 @@ -630,11 +642,17 @@ $(BUILD_DIR)/src/libultra/os/writebackdcache.o: MIPS_VERSION := -mips3 $(BUILD_DIR)/src/libultra/os/writebackdcacheall.o: MIPS_VERSION := -mips3 else $(BUILD_DIR)/src/libultra/%.o: CC := $(CC_OLD) + $(BUILD_DIR)/src/libultra/libc/ll.o: OPTFLAGS := -O1 $(BUILD_DIR)/src/libultra/libc/ll.o: MIPS_VERSION := -mips3 -32 +$(BUILD_DIR)/src/libultra/libc/ll.o: POSTPROCESS_OBJ := $(PYTHON) tools/set_o32abi_bit.py + $(BUILD_DIR)/src/libultra/libc/llcvt.o: OPTFLAGS := -O1 $(BUILD_DIR)/src/libultra/libc/llcvt.o: MIPS_VERSION := -mips3 -32 +$(BUILD_DIR)/src/libultra/libc/llcvt.o: POSTPROCESS_OBJ := $(PYTHON) tools/set_o32abi_bit.py + $(BUILD_DIR)/src/libultra/os/exceptasm.o: MIPS_VERSION := -mips3 -32 +$(BUILD_DIR)/src/libultra/os/exceptasm.o: POSTPROCESS_OBJ := $(PYTHON) tools/set_o32abi_bit.py endif $(BUILD_DIR)/src/code/%.o: ASOPTFLAGS := -O2 @@ -718,11 +736,6 @@ $(BUILD_DIR)/src/libultra/libc/ll.o: OPTFLAGS := -Ofast $(BUILD_DIR)/src/overlays/%.o: CFLAGS += -fno-merge-constants -mno-explicit-relocs -mno-split-addresses endif -SET_ABI_BIT = @: -$(BUILD_DIR)/src/libultra/os/exceptasm.o: SET_ABI_BIT = $(PYTHON) tools/set_o32abi_bit.py $@ -$(BUILD_DIR)/src/libultra/libc/ll.o: SET_ABI_BIT = $(PYTHON) tools/set_o32abi_bit.py $@ -$(BUILD_DIR)/src/libultra/libc/llcvt.o: SET_ABI_BIT = $(PYTHON) tools/set_o32abi_bit.py $@ - #### Main Targets ### all: rom compress @@ -899,10 +912,10 @@ ifeq ($(COMPILER),ido) # but strip doesn't know about file-relative offsets in .mdebug and doesn't relocate them, ld will # segfault unless .mdebug is removed $(OBJCOPY) --remove-section .mdebug $(@:.o=.tmp.o) $@ - $(SET_ABI_BIT) else $(CCAS) -c $(CCASFLAGS) $(MIPS_VERSION) $(ASOPTFLAGS) -o $@ $< endif + $(POSTPROCESS_OBJ) $@ $(OBJDUMP_CMD) # Incremental link to move z_message and z_game_over data into rodata @@ -933,7 +946,7 @@ ifneq ($(RUN_CC_CHECK),0) $(CC_CHECK) $< endif $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< - $(SET_ABI_BIT) + $(POSTPROCESS_OBJ) $@ $(OBJDUMP_CMD) $(BUILD_DIR)/src/audio/session_init.o: src/audio/session_init.c $(BUILD_DIR)/assets/audio/soundfont_sizes.h $(BUILD_DIR)/assets/audio/sequence_sizes.h diff --git a/src/boot/driverominit.c b/src/boot/driverominit.c index 7d1441cdd9..5ed69abe07 100644 --- a/src/boot/driverominit.c +++ b/src/boot/driverominit.c @@ -3,7 +3,14 @@ OSPiHandle __DriveRomHandle; OSPiHandle* osDriveRomInit(void) { +#if PLATFORM_IQUE && defined(NON_MATCHING) + // On iQue, the compiled output of this file is patched so that the + // `!first` check is always taken. For non-matching builds, we edit the + // source code instead. + static u32 first = false; +#else static u32 first = true; +#endif register s32 status; register u32 value; register u32 prevInt; diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c index a953bdb214..d219815102 100644 --- a/src/code/z_skelanime.c +++ b/src/code/z_skelanime.c @@ -849,7 +849,7 @@ AnimTask* AnimTaskQueue_NewTask(AnimTaskQueue* animTaskQueue, s32 type) { return task; } -#if PLATFORM_N64 +#if !PLATFORM_GC #define LINK_ANIMATION_OFFSET(addr, offset) \ (((uintptr_t)_link_animetionSegmentRomStart) + SEGMENT_OFFSET(addr) + (offset)) #else diff --git a/tools/disasm/ique-cn/files_boot.csv b/tools/disasm/ique-cn/files_boot.csv index 9a878030a2..0aae45345e 100644 --- a/tools/disasm/ique-cn/files_boot.csv +++ b/tools/disasm/ique-cn/files_boot.csv @@ -134,7 +134,7 @@ A7A0,8000ABF0,src/boot/boot_main B190,8000B5E0,src/boot/idle BD90,8000C1E0,src/boot/z_std_dma C500,8000C950,src/boot/zlib -FBB0,80010000,src/boot/driverominit +10310,80010760,src/boot/driverominit 10390,800107E0,src/libultra/io/vimgr 115B0,80011A00,src/libultra/io/pimgr 12940,80012D90,data/boot_common_80012D90 diff --git a/tools/patch_ique_driverominit.py b/tools/patch_ique_driverominit.py new file mode 100755 index 0000000000..f7ca9daac2 --- /dev/null +++ b/tools/patch_ique_driverominit.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +import struct, sys, argparse + +import elftools.elf.elffile + +# Patches driverominit.o to change bnez t6,3c to nop at offset 0x20 in the .text section + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument("file", help="input file") + args = parser.parse_args() + + with open(args.file, "r+b") as f: + elf = elftools.elf.elffile.ELFFile(f) + + text_offset = 0 + for section in elf.iter_sections(): + if section.name == ".text": + text_offset = section["sh_offset"] + break + + if text_offset == 0: + print("Error: .text section not found") + sys.exit(1) + + f.seek(text_offset + 0x20) + instruction = struct.unpack(">I", f.read(4))[0] + if instruction != 0x15C00006: # bnez t6,3c + print("Error: expected instruction not found, found 0x%08X" % instruction) + sys.exit(1) + + f.seek(text_offset + 0x20) + f.write(struct.pack(">I", 0x00000000)) # nop