On Thu, Feb 18, 2021 at 12:15 PM Project Revolution via Gcc <gcc@gcc.gnu.org> wrote: > > Hi GCC folks, > > We were working on a decompilation project for a Nintendo 64 title and > attempting to enable support for using GCC instead of the emulated IRIX > compiler and we ran into a big problem with how GCC generates relocations for > the MIPS target which appears to show that GCC is generating non-compliant > relocation data for MIPS target.
Try compiling with -fno-section-anchors . https://gcc.gnu.org/legacy-ml/gcc-help/2009-07/msg00455.html Thanks, Andrew > > In summary: the Nintendo 64 title has a limited amount of RAM (4MB, 8MB if > you add Expansion Pak, which our ROM target uses for debug reasons); in order > to accomplish this, the codebase packs actors/objects into overlays which the > game determines need to be loaded per room/system transition. Once loaded > into RAM, the game applies the overlay's relocations generated at compile > time to the code to move the data and code correctly and make sure the jumps > and loads get recalculated correctly. > > Unfortunately.. there's a problem. Here's the function that applies the > relocs to MIPS: > https://github.com/zeldaret/oot/blob/master/src/code/relocation.c > > While enabling overlays to be recompiled with GCC instead of the IDO > compiler, we have found the relocs generated did not guarantee 0x45/0x46 > (Hi/lo pairs) pairs to be 1:1, and GCC would share any possible hi/lo in O2 > mode. While O0 and O1 gcc overlays will work, or even Og, this is not a > solution for an N64 ROM due to limited RAM and space will quickly run out > since memory is so tight. While investigating why gcc will optimize relocs, > we have found the following: > > The MIPS ABI specified at > https://refspecs.linuxfoundation.org/elf/mipsabi.pdf on pages 79-80 (page 82 > regarding the GP caveat) demands that hi/los be in pairs). Thus, we have > found that the reloc data generated erroneously applies the relocation twice. > Several LOs following a HI seems to be in a spec, but several HIs following a > LO does not. This is causing issues for our relocation due to the relocs > being applied incorrectly as a result of non-compliant relocation data. It > turned out this reloc optimization is caused by an unmentioned, undocumented > GNU extension. > > We have found the GNU extension was ONLY ever mentioned here: > https://people.freebsd.org/~adrian/mips/20160819-mips-elf-reloc-gcc-5.3-3.diff > > Here is the file we compiled: > https://github.com/zeldaret/oot/blob/master/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c > > This is the line we used to compile it: > > mips-linux-gnu-gcc -c -O2 -c -G 0 -nostdinc -Iinclude -Isrc -Iassets -Ibuild > -I. -DNON_MATCHING=1 -DNON_EQUIVALENT=1 -DAVOID_UB=1 -mno-shared > -march=vr4300 -mfix4300 -mabi=32 -mhard-float -mdivide-breaks > -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -mno-abicalls > -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions > -fno-toplevel-reorder -ffreestanding -fwrapv -Wall -Wextra -g -fno-gcse > -fno-cse-follow-jumps -mno-load-store-pairs -mno-explicit-relocs > -fno-peephole2 -mips3 -o > build/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.o > src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c > > To note, we have tried with and without explicit relocs and with and without > peephole2 and with and without mips2/3 and it didnt make a difference: the > relocs were still noncompliant per the PDF posted earlier. We need a way to > turn this undocumented GNU extension off because it is causing relocs when > optimized to not be processed correctly. To note, our use case is attempting > to compile this repo with GCC (this file is a test case) but if you were to > compile the ROM with the Heishi4 file being compiled as GCC using the above > call (make any Makefile alterations to force the object to be GCC), spawn on > the SPOT00 map at the start of the game and go inside the castle town area > and observe the crash which takes like 60 seconds. This is ultimately what > we're trying to fix which following this rabbit hole leads us to this GNU > extension in a haystack hunt. Can you guys help us resolve this? > > v/r, > Revo >