devkitPro/wut

elf2rpl: Unable to create string objects

Closed this issue · 5 comments

First and foremost—this issue is not the result of the recent newlib changes - I suffer the same issue after checking out and building 9161baa (the earliest version of WUT that can be built without reverting to devkitPPC r27). I'm also unsure if this is an issue with devkitPPC itself or if the issue is within WUT.

The issue is that I cannot successfully create an std::string object within a WUT program. Attenping to do so will create a setup that compiles and links into an ELF successfully. However, elf2rpl will then spit out the below error and terminate with error code 255.

Unexpected symbol address in .rela.dyn section

The code to generate this error does not seem to be specific. I was able to generate this error within the sample projects as well. Within the helloworld example, renaming src/main.c to src/main.cpp and ensuring the necessary changes to CMakeLists.txt are made, then inserting #include <string> into main.cpp will still create a buildable and runnable program. However, adding std::string anywhere in the file (e.g. adding std::string myString = "Hello!"; to the top of main() will result in the above error.

Hey @CreeperMario,
Unfortunately, WUT does not currently contain support for building C++ applications. It is something that is being heavily worked on, but we are not at a point where it is yet possible.
Cheers, Brett

I suffer the same issue after checking out and building 9161baa (the earliest version of WUT that can be built without reverting to devkitPPC r27)

Ironically enough, everything builds fine when using devkitPPC r27, even when using the latest commit of WUT. The problem has been introduced by devkitPPC r29.

And so I decided to look into this issue further. For reference, here's what happens when I try to build a small program (see CMakeLists.txt and main.cpp) using devkitPPC r27 and r29-1.

I commented out lines 80-82 in wut-toolchain.cmake, so that CMake does not invoke elf2rpl on the resulting binary. This way, I am left with the uncompressed ELF file.

I decided to look at the .rela.dyn section in both versions of the binary (r27 and r29-1).

When built with devkitPPC r27, the .rela.dyn section contains 464 entries, while if built with devkitPPC r29, the section contains 1133 entries, and many of them seem to be duplicated entries (point to the same symbol address). Is this normal?

After performing further investigation into this, I found that, in terms of building the file I linked to above, elf2rpl stops on the 494th relocation.

Relocation section '.rela.dyn' at offset 0xbd880 contains 1133 entries:

 Offset     Info    Type            Sym.Value  Sym. Name + Addend
100031d1  00000016 R_PPC_RELATIVE               1000060

The address 0x01000060 represents a memory location before the code section even begins (at 0x02000000), hence why it is being reported by elf2rpl as an unexpected symbol.

In order to be a valid relocation, it must be a valid symbol or dynamic function import, or be within the confines of the code or data sections. This relocation is not an import or a symbol, and it resides within your system section, before the code section begins. Therefore, it is invalid.

Looking through the list of relocations, there seem to be many more that point to locations within the system section. This section is not copied into the final RPX file, correct? So why are relocations being made for it? And why does this only occur if C++ code is linked?

@CreeperMario Yeah system shouldn't be getting relocations. I think it should be possible to maybe rewrite those relocations to point to the appropriate import symbol, however. If I had to guess why it'd be a C++ issue, probably some vtable which has an RPL import in it for some reason? Could have been GCC optimizations gone wrong tbh.

EDIT: It might be possible to do a pass through relocations to move the system symbol over to the appropriate Wii U import symbol around here? Can't test personally but I'd say it's worth a shot.

exjam commented

Fixed in the rewrite branch.