Bug 24697 - ld powerpc 2.31.1 crashes when linking a library containing R_PPC_EMB_SDA21 relocation symbols
Summary: ld powerpc 2.31.1 crashes when linking a library containing R_PPC_EMB_SDA21 r...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.31
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-06-18 11:43 UTC by daan
Modified: 2019-08-29 11:40 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description daan 2019-06-18 11:43:07 UTC
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.
Comment 1 Alan Modra 2019-06-19 02:38:29 UTC
> 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..
Comment 2 Sourceware Commits 2019-06-19 04:38:39 UTC
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.
Comment 3 Sourceware Commits 2019-08-29 11:39:59 UTC
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.
Comment 4 Alan Modra 2019-08-29 11:40:39 UTC
Fixed, I believe.