splat
splat copied to clipboard
Allow setting a different alignment for each section
Currently, splat allows setting a subalign value for each YAML segment (e.g. "main"). This sets the subalign value in the linkerscript for all the sections in the segment (.text, .data, etc.).
This is a problem for those games that have different align values for different sections. For example, PS2 games have functions in .text with subalign 8, but symbols in .data might need a different subalign, e.g., 2.
Allowing per-subsegment subalign, such as:
- { start: 0x00112233, type: .data, name: path/to/file, subalign: 2 }
would allow splat to generate a linkerscript that would work without extra processing.
Fatal Frame 2 also suffers from this.
As far as I know it is not possible to specify different SUBALIGNs for different sections on the same segment on a linker script. This is caused by how splat generates linker scripts, since it puts all the sections (.text, .data, .rodata, etc) inside the same segment (or elf section), so the SUBALIGN is applied to all those sections.
You mentioned that you are processing the generated linker script. What changes are you doing exactly?
The workaround some PS2 projects took for this issue is to set the subalign to null on the yaml and just let the linker use the alignment specified for each section on each object. This works nice for C and C++ files since the compiler sets the alignments for each section appropriately (assuming you have the correct compiler).
This can be an issue for asm files that have not been converted to C/C++ yet since most people use modern GAS to build those, and modern GAS sets all the alignments to 0x10 instead of the required ones. The workaround is to patch those GAS-built objects after building them.
The hit_and_run and the parappa2 repos follow this workaround. The elf patcher is here and it is used like this on a Makefile and like this on a Ninja configure file.
Alternatively you could use the binutils-mips-ps2-decompals GAS fork instead of stock GAS to build those assembly files, the advantage being that you can pass flags to specify the alignment you want for each section in case you don't like the python script patcher.
https://github.com/Mikompilation/Himuro/blob/main/tools/python/fix_linkerscript.py https://github.com/Mikompilation/Himuro/blob/main/config/us/ff1.us.yaml Is what Fatal Frame 1 does
@AngheloAlf That is more or less the answer I was expecting, knowing how a linkerscript works, but wanted to know your opinion on this.
My approach right now is very crude: I set the smallest common SUBALIGN, which I think is 2 in my case, then parse the generated linkerscript and prepend each build/src/<FILE>.c.o(.<SECTION>); with . = ALIGN(., N); where N is the align value for the <SECTION>. Not very elegant but it works for now.
The workaround some PS2 projects took for this issue is to set the subalign to null on the yaml and just let the linker use the alignment specified for each section on each object.
I think this is probably the right thing to, eventually, do, but for now it doesn't work. I can't rule out the fact that there can be errors in my TU splits, thus the linker is not doing the right thing because of that, but I'm still early in the decompilation so I'll stick to my hack for now and revisit the yaml later when I have more evidence to work with.
For now, thanks a lot for the answer.