Bug 18167 - [2.25 regression] binutils fails to link gmp on ARM32
Summary: [2.25 regression] binutils fails to link gmp on ARM32
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-03-26 13:42 UTC by Matthias Klose
Modified: 2015-04-04 10:25 UTC (History)
1 user (show)

See Also:
Host:
Target: arm-linux-gnueabihf
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Klose 2015-03-26 13:42:36 UTC
seen when building gmp 6.0.0a on ARM32 linux only, other architectures work fine:

libtool: link: arm-linux-gnueabihf-gcc -std=gnu99 -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -O3 -Wl,-Bsymbolic-functions -Wl,-z -Wl,relro -o .libs/t-constants t-constants.o  ./.libs/libtests.a /build/buildd/gmp-6.0.0+dfsg/build/.libs/libgmp.so ../.libs/libgmp.so
/usr/bin/ld: copy reloc against protected `__gmp_binvert_limb_table' is invalid
/usr/bin/ld: failed to set dynamic section sizes: Bad value
collect2: error: ld returned 1 exit status
Makefile:760: recipe for target 't-constants' failed

likely exposed by the fixes for PR ld/pr15228, PR ld/pr17709
Comment 1 H.J. Lu 2015-03-26 14:18:08 UTC
All ELF targets with copy relocation should set
elf_backend_extern_protected_data to 1, like x86 in

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=031994d25c8c8dc392ceb43abc2dfd9a851bc384
Comment 2 Alan Modra 2015-03-26 15:05:36 UTC
Likely due to my PR 15228 fix.

HJ's advice is only reasonable if you have glibc and gcc changes that
a) make code generated for access to protected visibility variables in shared libraries effectively be the same as for default visibility variables, and
b) you have glibc changes that ensure you keep the semantics of protected visibility variables.

Otherwise all HJ's changes do is revert the PR 15228 fix, and you will silently generate buggy executables that have a copy of a protected variable in .dynbss that isn't used by the shared library defining that variable.  ie. you've broken the semantics of protected variables.  If either the executable or the shared library update the variable's value, then they see different values in a variable that has only one definition.

I also think HJ's linker changes are unsafe since there is no attempt to detect shared libraries that are compiled without the as yet uncommitted gcc changes.
Comment 3 cvs-commit@gcc.gnu.org 2015-03-27 05:53:07 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b84171287ffe60dd1e7c02262a0493862fa21a97

commit b84171287ffe60dd1e7c02262a0493862fa21a97
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Mar 27 15:41:05 2015 +1030

    Relax PR 15228 protected visibility restriction
    
    Allows .dynbss copy of shared library protected visibility variables
    if they are read-only.
    
    To recap: Copying a variable from a shared library into an executable's
    .dynbss is an old hack invented for non-PIC executables, to avoid the
    text relocations you'd otherwise need to access a shared library
    variable.  This works with ELF shared libraries because global
    symbols can be overridden.  The trouble is that protected visibility
    symbols can't be overridden.  A shared library will continue to access
    it's own protected visibility variable while the executable accesses a
    copy.  If either the shared library or the executable updates the
    value then the copy diverges from the original.  This is wrong since
    there is only one definition of the variable in the application.
    
    So I made the linker report an error on attempting to copy protected
    visibility variables into .dynbss.  However, you'll notice the above
    paragraph contains an "If".  An application that does not modify the
    variable value remains correct even though two copies of the variable
    exist.  The linker can detect this situation if the variable was
    defined in a read-only section.
    
    	PR ld/15228
    	PR ld/18167
    	* elflink.c (elf_merge_st_other): Add "sec" parameter.  Don't set
    	protected_def when symbol section is read-only.  Adjust all calls.
    	* elf-bfd.h (struct elf_link_hash_entry): Update protected_def comment.
Comment 4 Alan Modra 2015-03-27 05:55:31 UTC
Matthias, please check that the patch I've just committed fixes the problem in gmp.
Comment 5 Matthias Klose 2015-03-27 13:28:28 UTC
yes, the patch fixes the gmp build issue on ARM32.
Comment 6 cvs-commit@gcc.gnu.org 2015-04-03 23:31:20 UTC
The binutils-2_25-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=12aca65e0f9148bf136a9f4cfc2187aa485a143a

commit 12aca65e0f9148bf136a9f4cfc2187aa485a143a
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Mar 27 15:41:05 2015 +1030

    Relax PR 15228 protected visibility restriction
    
    Allows .dynbss copy of shared library protected visibility variables
    if they are read-only.
    
    To recap: Copying a variable from a shared library into an executable's
    .dynbss is an old hack invented for non-PIC executables, to avoid the
    text relocations you'd otherwise need to access a shared library
    variable.  This works with ELF shared libraries because global
    symbols can be overridden.  The trouble is that protected visibility
    symbols can't be overridden.  A shared library will continue to access
    it's own protected visibility variable while the executable accesses a
    copy.  If either the shared library or the executable updates the
    value then the copy diverges from the original.  This is wrong since
    there is only one definition of the variable in the application.
    
    So I made the linker report an error on attempting to copy protected
    visibility variables into .dynbss.  However, you'll notice the above
    paragraph contains an "If".  An application that does not modify the
    variable value remains correct even though two copies of the variable
    exist.  The linker can detect this situation if the variable was
    defined in a read-only section.
    
    	PR ld/15228
    	PR ld/18167
    	* elflink.c (elf_merge_st_other): Add "sec" parameter.  Don't set
    	protected_def when symbol section is read-only.  Adjust all calls.
    	* elf-bfd.h (struct elf_link_hash_entry): Update protected_def comment.
Comment 7 Alan Modra 2015-04-04 10:25:24 UTC
Fixed