Bug 19579 - [Regression] link error linking fortran code with PIE
Summary: [Regression] link error linking fortran code with PIE
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.26
: P2 normal
Target Milestone: 2.27
Assignee: H.J. Lu
URL:
Keywords:
Depends on:
Blocks: 21306
  Show dependency treegraph
 
Reported: 2016-02-08 11:39 UTC by Matthias Klose
Modified: 2017-06-13 14:58 UTC (History)
7 users (show)

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


Attachments
Proposed Patch (1.85 KB, patch)
2016-02-23 16:19 UTC, Nick Clifton
Details | Diff
A patch (1.18 KB, patch)
2016-03-02 16:53 UTC, H.J. Lu
Details | Diff
An updated patch (1.33 KB, patch)
2016-03-02 21:39 UTC, H.J. Lu
Details | Diff
A new patch (1.43 KB, patch)
2016-03-02 22:50 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Klose 2016-02-08 11:39:20 UTC
seen with 2.26 on s390x-linux-gnu, building the mopac7 package.

s390x-linux-gnu-ld --build-id --eh-frame-hdr -m elf64_s390 --hash-style=gnu --as-needed -dynamic-linker /lib/ld64.so.1 -pie -z relro -o mopac7 Scrt1.o crti.o crtbeginS.o mopac7app.o libmopac7.so libgfortran.so libm.so libgfortran.so libm.so libgcc_s.so libgcc.a libm.so libgcc_s.so libgcc.a libc.so libgcc_s.so libgcc.a crtend.o crtn.o
s390x-linux-gnu-ld: final link failed: Nonrepresentable section on output

test case at
http://people.canonical.com/~doko/tmp/s390x-tst.tar.xz

original build log and sources:
https://launchpad.net/ubuntu/+source/mopac7/1.15-6ubuntu1

last successful build was with a version binutils 2.24.90 version.
Comment 1 Nick Clifton 2016-02-23 16:19:16 UTC
Created attachment 9033 [details]
Proposed Patch

Hi Matthias,

  Please try out this patch and see if it works for you.

  I am not 100% happy with this solution however, as it is a generic fix for
  what looks like a target specific problem.  IE I could not find out what it
  was about the s390 target that was triggering this problem.  Of course I
  might be wrong, the problem might be generic as well, but in that case, why
  has no one else reported it ?

Cheers
  Nick
Comment 2 Matthias Klose 2016-02-23 18:19:01 UTC
no, the link ends exit status one, and a partially written .libs/mopac7.

$ file .libs/mopac7
.libs/mopac7: data

The binutils built with this patch doesn't show any regressions in the testsuite. I'll start a debug build, and will report back tomorrow.
Comment 3 Matthias Klose 2016-02-23 18:19:24 UTC
forgot to say, no error message was given.
Comment 4 Matthias Klose 2016-02-24 15:01:22 UTC
Breakpoint 1, xexit (code=1) at ../../libiberty/xexit.c:48
48      {
(gdb) bt
#0  xexit (code=1) at ../../libiberty/xexit.c:48
#1  0x000002aa00025020 in ldwrite () at ../../ld/ldwrite.c:590
#2  0x000002aa000237a4 in main (argc=41, argv=0x3fffffff768) at ../../ld/ldmain.c:430

test case at
http://people.canonical.com/~doko/tmp/s390x-tst2.tar.xz
Comment 5 Andreas Krebbel 2016-02-26 19:08:57 UTC
I can reproduce the failure building mopac7-1.15 with -fPIC and -pie.  The problem disappears when omitting -pie.

The error gets reported after elf_s390_finish_dynamic_symbol returned false here:

      else if (bfd_link_pic (info)
	  && SYMBOL_REFERENCES_LOCAL (info, h))
	{
	  /* If this is a static link, or it is a -Bsymbolic link and
	     the symbol is defined locally or was forced to be local
	     because of a version file, we just want to emit a
	     RELATIVE reloc.  The entry in the global offset table
	     will already have been initialized in the
	     relocate_section function.  */
---->	  if (!h->def_regular)
	    return FALSE;

The symbol in question is geovar_ :

$ readelf -s ./.libs/libmopac7.so | grep geovar_
   388: 000000000399f920  8656 OBJECT  GLOBAL DEFAULT   22 geovar_
  5819: 000000000399f920  8656 OBJECT  GLOBAL DEFAULT   22 geovar_
$ readelf -s mopac7app.o | grep geovar
   160: 0000000000000008  5768 OBJECT  GLOBAL DEFAULT  COM geovar_

It is not clear to me yet how this is supposed to work correctly yet. As usual I've tried to figure out what x86 is doing but I ran into similiar problems:

with 2.23.52 I see the very same problem as on s390:

/bin/sh ../libtool --tag=F77   --mode=link gfortran  -g -O2 -std=legacy -fno-automatic -fPIC -lm -Wl,--
gfortran -g -O2 -std=legacy -fno-automatic -fPIC -Wl,--as-needed -Wl,-z -Wl,defs -pie -o .libs/mopac7 m
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
make[1]: *** [mopac7] Error 1

Using head binutils however I get:
gfortran -g -O2 -std=legacy -fno-automatic -fPIC -Wl,--as-needed -Wl,-z -Wl,defs -pie -o .libs/mopac7 mopac7app.o  ./.libs/libmopac7.so -lm  -Wl,--rpath -Wl,/home/andreas/mopac/install/lib
/home/andreas/binutils/binutils-26022016-install/bin/ld: mopac7app.o: relocation R_X86_64_PC32 against undefined symbol `geokst_' can not be used when making a shared object; recompile with -fPIC
/home/andreas/binutils/binutils-26022016-install/bin/ld: final link failed: Bad value

Although everything is built with -fPIC

I'll continue next week.
Comment 6 H.J. Lu 2016-02-26 22:54:43 UTC
(In reply to Andreas Krebbel from comment #5)

> Using head binutils however I get:
> gfortran -g -O2 -std=legacy -fno-automatic -fPIC -Wl,--as-needed -Wl,-z
> -Wl,defs -pie -o .libs/mopac7 mopac7app.o  ./.libs/libmopac7.so -lm 
> -Wl,--rpath -Wl,/home/andreas/mopac/install/lib
> /home/andreas/binutils/binutils-26022016-install/bin/ld: mopac7app.o:
> relocation R_X86_64_PC32 against undefined symbol `geokst_' can not be used
> when making a shared object; recompile with -fPIC
> /home/andreas/binutils/binutils-26022016-install/bin/ld: final link failed:
> Bad value
> 
> Although everything is built with -fPIC
> 

I can reproduce it on Fedora 23.  It is a bug in redhat-rpm-config, which
has redhat-hardened-cc1 and redhat-hardened-ld.  But there is no
redhat-hardened-f951.  mopac7app.o isn't compiled with PIE/PIC.
Comment 7 Andreas Krebbel 2016-03-02 09:24:27 UTC
(In reply to H.J. Lu from comment #6)
> I can reproduce it on Fedora 23.  It is a bug in redhat-rpm-config, which
> has redhat-hardened-cc1 and redhat-hardened-ld.  But there is no
> redhat-hardened-f951.  mopac7app.o isn't compiled with PIE/PIC.

In my tests mopac7app.o was built with -fPIC. The problem seems to occur since this commit:

commit b31bcacc489d6ede2e9bdfa9905de0ebfd919454
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Oct 16 03:14:40 2015 -0700

    Convert mov to lea for loading address of local common symbol
    
    There is no need to check def_regular when converting mov to lea for
    loading address of local symbols since def_regular may be false for
    common symbols and SYMBOL_REFERENCES_LOCAL is sufficient.
    
    bfd/
    
        * elf32-i386.c (elf_i386_convert_mov_to_lea): Don't check
        def_regular.
        * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Likewise.


Before that change there was the same problem is currently on S/390:

/bin/sh ../libtool --tag=F77   --mode=link gfortran  -g -O2 -std=legacy -fno-automatic -fPIC -lm -Wl,--as-needed -Wl,-z,defs -pie -o mopac7 mopac7app.o libmopac7.la -lm 
gfortran -g -O2 -std=legacy -fno-automatic -fPIC -Wl,--as-needed -Wl,-z -Wl,defs -pie -o .libs/mopac7 mopac7app.o  ./.libs/libmopac7.so -lm  -Wl,--rpath -Wl,/home/andreas/mopac/install/lib
/home/andreas/binutils/binutils-before-install/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
make[1]: *** [mopac7] Error 1
Comment 8 H.J. Lu 2016-03-02 16:06:21 UTC
[hjl@gnu-6 pr19579]$ cat x.c
int foo[10];

extern void bar (void);

int
main ()
{
  bar ();
  return foo[0] != 0;
}
[hjl@gnu-6 pr19579]$ cat y.c
void
bar (void)
{
}
[hjl@gnu-6 pr19579]$ cat foo.c
int foo[20];;
[hjl@gnu-6 pr19579]$ make
gcc  -pie -fPIE -g   -c -o x.o x.c
gcc  -pie -fPIE -g   -c -o y.o y.c
gcc  -pie -fPIE -g -fPIC   -c -o foo.o foo.c
gcc  -pie -shared -o libfoo.so foo.o
gcc  -pie -o x x.o y.o libfoo.so -Wl,-R.
/usr/local/bin/ld: x.o: relocation R_X86_64_PC32 against undefined symbol `foo' can not be used when making a shared object; recompile with -fPIC
/usr/local/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Makefile:15: recipe for target 'x' failed
make: *** [x] Error 1
[hjl@gnu-6 pr19579]$
Comment 9 H.J. Lu 2016-03-02 16:53:54 UTC
Created attachment 9059 [details]
A patch

Please try this patch.
Comment 10 H.J. Lu 2016-03-02 21:05:46 UTC
(In reply to H.J. Lu from comment #9)
> Created attachment 9059 [details]
> A patch
> 
> Please try this patch.

Doesn't work:

[hjl@gnu-6 pr19579]$ cat x.c
#include <stdio.h>

int foo[1];
int bar[1];

extern int *foo_p (void);
extern int *bar_p (void);

int
main ()
{
  if (foo[0] == 0 && foo == foo_p () && bar[0] == 0 && bar == bar_p ())
    printf ("PASS\n");
  return 0;
}
[hjl@gnu-6 pr19579]$ cat foo.c
int foo[2];
int bar[2] = { -1, -1 };

int *
foo_p (void)
{
  return foo;
}

int *
bar_p (void)
{
  return bar;
}
[hjl@gnu-6 pr19579]$ make
gcc  -pie -fPIE -O0   -c -o x.o x.c
gcc  -pie -fPIE -O0 -fPIC   -c -o foo.o foo.c
gcc  -pie -shared -o libfoo.so foo.o
gcc  -pie -o x x.o libfoo.so -Wl,-R.
/usr/local/bin/ld: Warning: size of symbol `bar' changed from 4 in x.o to 8 in libfoo.so
/usr/local/bin/ld: x.o(.text+0x24): unresolvable R_X86_64_PC32 relocation against symbol `bar'
/usr/local/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Makefile:17: recipe for target 'x' failed
make: *** [x] Error 1
[hjl@gnu-6 pr19579]$
Comment 11 H.J. Lu 2016-03-02 21:39:52 UTC
Created attachment 9060 [details]
An updated patch

Try this one.
Comment 12 H.J. Lu 2016-03-02 22:50:40 UTC
Created attachment 9061 [details]
A new patch
Comment 13 Andreas Krebbel 2016-03-04 07:03:19 UTC
(In reply to H.J. Lu from comment #12)
> Created attachment 9061 [details]
> A new patch

Problem is fixed on s390 with this patch. Thanks!
Comment 14 cvs-commit@gcc.gnu.org 2016-03-04 14:39:33 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit 07492f668d2173da7a2bda3707ff0985e0f460b6
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Mar 4 06:37:34 2016 -0800

    Treat common symbol in executable as definition
    
    Common symbol in executable is a definition, which overrides definition
    from shared objects.  When linker sees a new definition from a shared
    object, the new dynamic definition should be overridden by the previous
    common symbol in executable.
    
    bfd/
    
    	PR ld/19579
    	* elflink.c (_bfd_elf_merge_symbol): Treat common symbol in
    	executable as definition if the new definition comes from a
    	shared library.
    
    ld/
    
    	PR ld/19579
    	* testsuite/ld-elf/pr19579a.c: New file.
    	* testsuite/ld-elf/pr19579b.c: Likewise.
    	* testsuite/ld-elf/shared.exp: Run PR ld/19579 test.
Comment 15 H.J. Lu 2016-03-04 14:40:11 UTC
Fixed on master so far.
Comment 16 cvs-commit@gcc.gnu.org 2016-03-08 13:31:47 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit 202ac193bbbecc96a4978d1ac3d17148253f9b01
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Mar 8 05:28:55 2016 -0800

    Group common symbol checking together
    
    	PR ld/19579
    	* elflink.c (_bfd_elf_merge_symbol): Group common symbol checking
    	together.
Comment 17 cvs-commit@gcc.gnu.org 2016-03-09 14:01:54 UTC
The binutils-2_26-branch branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit 1134e6ce012575e6d0e99933d0d29cc7978af9af
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Mar 9 05:59:20 2016 -0800

    Treat common symbol in executable as definition
    
    Common symbol in executable is a definition, which overrides definition
    from shared objects.  When linker sees a new definition from a shared
    object, the new dynamic definition should be overridden by the previous
    common symbol in executable.
    
    Backport from master
    
    bfd/
    
    	PR ld/19579
    	* elflink.c (_bfd_elf_merge_symbol): Group common symbol checking
    	together.
    
    	* elflink.c (_bfd_elf_merge_symbol): Treat common symbol in
    	executable as definition if the new definition comes from a
    	shared library.
    
    ld/
    
    	PR ld/19579
    	* testsuite/ld-elf/pr19579a.c: New file.
    	* testsuite/ld-elf/pr19579b.c: Likewise.
    	* testsuite/ld-elf/shared.exp: Run PR ld/19579 test.
Comment 18 H.J. Lu 2016-03-09 14:02:36 UTC
Fixed on master and 2.26 branch.
Comment 19 H.J. Lu 2017-04-05 16:39:00 UTC
Reopen
Comment 20 H.J. Lu 2017-04-05 16:39:28 UTC
*** Bug 21306 has been marked as a duplicate of this bug. ***
Comment 21 cvs-commit@gcc.gnu.org 2017-04-07 14:41:18 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit 8170f7693bc0a9442c0aa280197925db92d48ca6
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Apr 7 07:40:14 2017 -0700

    ELF: Check ELF_COMMON_DEF_P for common symbols
    
    Since common symbols that are turned into definitions don't have the
    DEF_REGULAR flag set, we need to check ELF_COMMON_DEF_P for common
    symbols.
    
    bfd/
    
    	PR ld/19579
    	PR ld/21306
    	* elf32-s390.c (elf_s390_finish_dynamic_symbol): Check
    	ELF_COMMON_DEF_P for common symbols.
    	* elf64-s390.c (elf_s390_finish_dynamic_symbol): Likewise.
    	* elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
    	* elflink.c (_bfd_elf_merge_symbol): Revert commits
    	202ac193bbbecc96a4978d1ac3d17148253f9b01 and
    	07492f668d2173da7a2bda3707ff0985e0f460b6.
    
    ld/
    
    	PR ld/19579
    	PR ld/21306
    	* testsuite/ld-elf/pr19579a.c (main): Updated.
Comment 22 cvs-commit@gcc.gnu.org 2017-04-10 16:04:28 UTC
The binutils-2_28-branch branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit 5a0ac7ba3c5277b3ab04f55de23bccb7614a9e59
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Apr 7 07:40:14 2017 -0700

    ELF: Check ELF_COMMON_DEF_P for common symbols
    
    Since common symbols that are turned into definitions don't have the
    DEF_REGULAR flag set, we need to check ELF_COMMON_DEF_P for common
    symbols.
    
    bfd/
    
    	PR ld/19579
    	PR ld/21306
    	* elf32-s390.c (elf_s390_finish_dynamic_symbol): Check
    	ELF_COMMON_DEF_P for common symbols.
    	* elf64-s390.c (elf_s390_finish_dynamic_symbol): Likewise.
    	* elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
    	* elflink.c (_bfd_elf_merge_symbol): Revert commits
    	202ac193bbbecc96a4978d1ac3d17148253f9b01 and
    	07492f668d2173da7a2bda3707ff0985e0f460b6.
    
    ld/
    
    	PR ld/19579
    	PR ld/21306
    	* testsuite/ld-elf/pr19579a.c (main): Updated.
    
    (cherry picked from commit 8170f7693bc0a9442c0aa280197925db92d48ca6)
Comment 23 H.J. Lu 2017-04-10 16:07:28 UTC
Fixed for master and 2.28 branch.
Comment 24 James Clarke 2017-05-25 18:47:36 UTC
This is still broken on AArch64. I have just submitted a patch to the mailing list.
Comment 25 cvs-commit@gcc.gnu.org 2017-06-06 13:32:17 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit 0ee3a6dbd06b88a4e02f3f46c3ec036fd951400b
Author: James Clarke <jrtc27@jrtc27.com>
Date:   Tue Jun 6 14:30:47 2017 +0100

    Fix AArch64 in the same way as other targets updated in 8170f7693bc0a9442c0aa280197925db92d48ca6.
    
    	PR ld/19579
    	* elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol): Check
    	ELF_COMMON_DEF_P for common symbols.
Comment 26 Renlin Li 2017-06-08 16:16:29 UTC
(In reply to James Clarke from comment #24)
> This is still broken on AArch64. I have just submitted a patch to the
> mailing list.

Hi James, do you have plan to backport the fix to 2.28 branch?

Thanks!
Comment 27 cvs-commit@gcc.gnu.org 2017-06-13 14:58:46 UTC
The binutils-2_28-branch branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit fcc15c89c356c73c94581dd524d0b9ca596014b1
Author: James Clarke <jrtc27@jrtc27.com>
Date:   Tue Jun 13 15:55:02 2017 +0100

    Fix handling of relocations against common symbols on AArch64.
    
    	PR ld/19579
    	* elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol): Check
    	ELF_COMMON_DEF_P for common symbols.