At our project we need to link a 3rd party elf file for the powerpc gnu linker (ld 2.31.1). This elf file contains symbols that use the R_PPC_EMB_SDA21 relocation type. Now the linker gives error message 'relocation R_PPC_EMB_SDA21 cannot be used when making a shared object' and then crashes with a bus-error and message 'double free or corruption (out)' Although I am not entire sure how to fix the R_PPC_EMB_SDA21 problem and if that is actually a correct error message, for sure the linker should never crash with 'double free or corruption (out)'. Reproduce with: usr/bin/powerpc-linux-gnu-gcc path/to/elf_file_with_R_PPC_EMB_SDA21.elf Unfortunately I can't reproduce it without our 3rd party elf file, because I don't know how to create a (test) library containing R_PPC_EMB_SDA21 relocation symbols. We use Debian Buster (on Intel), before on Debian Stretch with gcc 6.3.0 and corresponding linker we didn't had that problem.
> on Debian Stretch with gcc 6.3.0 and > corresponding linker we didn't had that problem. If that is the case you were not using the debian stretch linker to link your 3rd. party ELF file into a shared library. The error message dates back to 1996, git commit e25a798839b. Also, from a quick look at the EABI definition of R_PPC_EMB_SDA21 I believe the GNU ld implementation for that relocation has been broken ever since GNU ld recognized it. R_PPC_EMB_SDA21 is supposed to operate on the least significant 21 bits of the 24-bit field at r_offset according to the EABI document I have, version 1.0 dated Jan 1995. GNU ld operates on a 32-bit field at r_offset, which means we have an inconsistency that matters for big-endian targets. Fixing GNU ld would not be hard for someone familiar with the sources, and you could easily be compatible with GNU as objects (that emit R_PPC_EMB_SDA21 operating on a 32-bit field) and object files complying with the EABI by simply masking off the two low bits of r_offset. However, given the fact that no one has bothered to do so in 23 years suggests that no one will take action on this bug. The double free has likely already been fixed..
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6f5601c4d0ad43254244f1b624900cdd5afd02ba commit 6f5601c4d0ad43254244f1b624900cdd5afd02ba Author: Alan Modra <amodra@gmail.com> Date: Wed Jun 19 13:55:59 2019 +0930 PR24697, R_PPC_EMB_SDA21 relocation PR 24697 * elf32-ppc.c (ppc_elf_relocate_section): Don't read insn for R_PPC_EMB_RELSDA. Mask low bit of R_PPC_EMB_SDA21 r_offset.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c0d9f31dbd8765dd925e6a4b4acdb9b23d1706f6 commit c0d9f31dbd8765dd925e6a4b4acdb9b23d1706f6 Author: Alan Modra <amodra@gmail.com> Date: Thu Aug 29 18:35:54 2019 +0930 PR24697, R_PPC_EMB_SDA21 cannot be used when making a shared object This removes a restriction on various R_PPC_EMB relocations that has been present for ppc32 since 1996-04-26 git commit e25a798839. As far as I know, only those relocs that would require addressing via r2 for .sdata2/.sbss2 access are disallowed in shared libraries. PR 24697 * elf32-ppc.c (ppc_elf_check_relocs): Call bad_shared_reloc when !bfd_link_executable for R_PPC_EMB_SDA2I16 and R_PPC_EMB_SDA2REL. Don't call bad_shared_reloc for any other reloc.
Fixed, I believe.