-
Notifications
You must be signed in to change notification settings - Fork 134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes to use unpatched binutils for linking IRX #253
Conversation
a4ff5f7
to
20e47ee
Compare
@uyjulian what's the status of this draft PR? |
Still a work in progress |
Perhaps instead of |
Why not |
Also note that @frno7 made some great iop tools here: I'm already using the |
The iopmod tools are intended to be compatible with PS2SDK, in the sense that its symbols such as |
Since we now have 2 toolchains in the CI for the IOP (an irx and an elf version), I would like to move forward with this change as well so we can remove the irx toolchain once completed. I've tested this PR with the following findings:
On a side note: I would like to have https://github.com/frno7/iopmod/ tools available in ps2sdk, and the CI. So we can use iopmod-info and perhaps also iopmod-link. @fjtrujy will you make the PR for adding these tools? I've been testing with this patch and both elf-to-irx (iopmod-link and elftypechanger) tools, but so far I've only managed to produce IRX files that don't run. |
Yes, I will try to do it today. I will add the tools to the |
The remaining issue is figuring out why the IOP linker (its code in loadcore, udnl) does not accept the file. The reason why the linker script strips sections is because it is mandatory that those sections not be there or the IOP linker does not accept the file. |
978087b
to
a972a66
Compare
I believe the remaining issue is that OPL black screens. wLE works fine. I'll debug this more later |
What’s the status of this? Would be really nice to use mainstream tools for IOP |
OPL is currently broken. |
a972a66
to
c6324d8
Compare
c6324d8
to
d7db829
Compare
OPL works now. I've unmarked this as draft |
Could you make a comparison between binaries sizes and/or performance? Cheers |
d7db829
to
10076ec
Compare
I removed the I did a size comparison. Before PR for mcman: 76,696 bytes Other than the section reordering, there is no change in code generation. |
Could you try to set the same max page size than EE? if I remember properly it was 128. Default value in newer GCCs was 4096 |
10076ec
to
ec1496d
Compare
Yes, it works. The size after PR is still 76,454 bytes |
This PR looks great for me, just for curiosity, I suppose that now you have some more bytes available in OPL, I hope this will help you to increase game compatibility |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great progress!
The new tool (ps2-irxgen) looks very complex compared to the one from @frno7 (iopmod-link), yet they seem to do the same (convert elf to irx)?
Are they compatible or does your tool do more things?
One difference I see is the "relocations". The linker flags do --emit-relocs
, and then ps2-irxgen seems to use these. What does this do?
@fjtrujy did you manage to get the iopmod tools into ps2dev?
IOP_LDFLAGS := -nostdlib -s $(IOP_LDFLAGS) | ||
IOP_LDFLAGS := -Wl,--gpsize=0 -Wl,-G0 -Wl,--nmagic -Wl,--orphan-handling=error -Wl,--discard-all -Wl,--gc-sections -Wl,--emit-relocs -nostdlib -Wl,-z,max-page-size=128 -Wl,--no-relax $(IOP_LDFLAGS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain all these flags and why the are needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--gpsize=0
Set the maximum size of objects to be optimized using the GP register to size. This is only meaningful for object file formats such as MIPS ELF that support putting large and small objects into different sections. This is ignored for other object file formats.
-G0
Set the maximum size of objects to be optimized using the GP register to size. This is only meaningful for object file formats such as MIPS ELF that support putting large and small objects into different sections. This is ignored for other object file formats.
--nmagic
Turn off page alignment of sections, and disable linking against shared libraries. If the output format supports Unix style magic numbers, mark the output as "NMAGIC".
--orphan-handling=error
Control how orphan sections are handled. An orphan section is one not specifically mentioned in a linker script.
The linker will exit with an error if any orphan section is found.
--discard-all
Delete all local symbols.
--gc-sections
Enable garbage collection of unused input sections. It is ignored on targets that do not support this option. The default behaviour (of not performing this garbage collection) can be restored by specifying --no-gc-sections on the command line. Note that garbage collection for COFF and PE format targets is supported, but the implementation is currently considered to be experimental.
--gc-sections decides which input sections are used by examining symbols and relocations. The section containing the entry symbol and all sections containing symbols undefined on the command-line will be kept, as will sections containing symbols referenced by dynamic objects. Note that when building shared libraries, the linker must assume that any visible symbol is referenced. Once this initial set of sections has been determined, the linker recursively marks as used any section referenced by their relocations. See --entry, --undefined, and --gc-keep-exported.
This option can be set when doing a partial link (enabled with option -r). In this case the root of symbols kept must be explicitly specified either by one of the options --entry, --undefined, or --gc-keep-exported or by a "ENTRY" command in the linker script.
As a GNU extension, ELF input sections marked with the "SHF_GNU_RETAIN" flag will not be garbage collected.
--emit-relocs
Leave relocation sections and contents in fully linked executables. Post link analysis and optimization tools may need this information in order to perform correct modifications of executables. This results in larger executables.
This option is currently only supported on ELF platforms.
-z,max-page-size=128
The recognized keywords are:
Set the maximum memory page size supported to 128.
--no-relax
An option with machine dependent effects. This option is only supported on a few targets.
On some platforms the --relax option performs target specific, global optimizations that become possible when the linker resolves addressing in the program, such as relaxing address modes, synthesizing new instructions, selecting shorter version of current instructions, and combining constant values.
On some platforms these link time global optimizations may make symbolic debugging of the resulting executable impossible. This is known to be the case for the Matsushita MN10200 and MN10300 family of processors.
On platforms where the feature is supported, the option --no-relax will disable it.
On platforms where the feature is not supported, both --relax and --no-relax are accepted, but ignored.
It probably does different stuff than Relocations are necessary so that LOADCORE can move the .irx contents anywhere in memory and still have it running. However, the symbols associated with those relocations are not necessary, so The reason to remove the symbols is because of RAM limitations. Unlike loading EE ELF files where only the necessary sections are read, MODLOAD will read the whole IRX file into memory. |
Can't we use
This is the only thing iopmod-link does I think.
I think the linkfile can do this (or already does this?).
So this is size optimization, and an improvement over iopmod-link? |
I believe that is the case.
It moves the section definition, but not the section contents. For some reason the section contents are still put near the end of the file when using
Correct, |
Rearranging the arguments to
Isn’t GNU |
I tried using GNU Also I tried using the |
I assume |
In fact, it does work. :-) As an experiment I added static void strip_module(struct file f)
{
Elf_Ehdr *ehdr = f.data;
Elf_Shdr *shdr;
Elf_Sym *sym;
elf_for_each_sym (sym, shdr, ehdr)
sym->st_name = 0;
} to $(MODULE_IRX): %.irx : %.iop
$(QUIET_LINK)$(IOPMOD_LINK) --strip -o $@ $<
$(QUIET_LINK)$(CROSS_COMPILE)objcopy $@ $@
$(QUIET_LINK)$(IOPMOD_LINK) -o $@ $@ and with
as opposed to the previous size of
saving in total 744 bytes for this particular IRX. It works with the PlayStation 2 hardware too. :-) |
With However I would prefer to use @uyjulian what do you think about using |
Personally I find using a single tool So in that case I would prefer to use In the future I may improve on the import/export table handling/generation, but that's all I'm going to do on this PR for now since I spent quite a bit of time to get this in a working state. |
Fair enough, ready for merge then? |
Yes, merging |
@rickgaiser, yes, eventually. See frno7/iopmod#11. I’ll consider ‘compacting’ sections too. If it’s simple enough (shifting subsequent memory and adjusting section offsets accordingly whilst honouring alignment restrictions), @uyjulian, the main benefit, in my opinion, for retaining |
When comparing an IRX file generated by the old toolchain to an IRX file generated by the new toolchain I find something very interesting: First few lines output of
First few lines output of
Most noticable difference is the iopmod version and name. They are wrong and seem to be off by 1 byte. Looks like an alignment issue in either |
May be either alignment or off by one issue. I will check it out later |
Tested: OPL works