riscv/flat: link with --no-relax
ld relaxes position independent sequences into absolute ones as soon as the
target address fits a 12 bit immediate. That only happens in small images,
and a bFLT is loaded at an arbitrary base, so those addresses are simply
wrong. It lands on the register_tm_clones / deregister_tm_clones pair that
.init_array calls before main, so a small binary dies with SIGSEGV before it
ever reaches main:
small image: li a0,1024 <- absolute, no relocation
large image: addi a0,gp,-1796 <- gp relative, survives relocation
Diagnosed on uClibc-ng's testsuite, where the twelve failures of the
riscv32 noMMU FLAT target were exactly the binaries small enough for this:
tiny plus the tests whose main is compiled out by feature guards. With
--no-relax five of the six recheck cleanly (getrpcent, bug-strspn1,
tst-strxfrm and exec-null, plus the -O2 twins).
Not a binutils regression: a cross link of the same objects with binutils
2.46 instead of 2.39 produces the same absolute form. For ld the link *is*
a fixed address executable -- nothing in it says the image will be moved --
so the flag belongs on our side. elf2flt's ld-elf2flt would be the better
place, since it already injects the linker script and --emit-relocs.
Signed-off-by: Ramin Moussavi <ramin.moussavi@yacoub.de>
Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>