Bug 10144

Summary: mips/ld: non-dynamic relocations refer to dynamic symbol
Product: binutils Reporter: Aurelien Jarno <aurelien>
Component: ldAssignee: Maciej W. Rozycki <macro>
Status: RESOLVED FIXED    
Severity: normal CC: bug-binutils, doko, rixed, rmansfield, rsandifo, tg
Priority: P2    
Version: 2.20   
Target Milestone: ---   
Host: mips-unknown-linux-gnu Target: mips-unknown-linux-gnu
Build: mips-unknown-linux-gnu Last reconfirmed:
Bug Depends on:    
Bug Blocks: 26080    
Attachments: testcase
New minimal testcase
Testcase #3 (with .c .s .o/.so)
Testcase with C code and makefile

Description Aurelien Jarno 2009-05-11 13:59:32 UTC
ld from binutils version 2.19.1, but also from the trunk version, is failing to 
link some objects on mips and mipsel, o32 ABI, with the following error:

| ld: non-dynamic relocations refer to dynamic symbol pthread_cancel@@GLIBC_2.0
| ld: failed to set dynamic section sizes: Bad value

This happens for example during the bootstrap of gcc 4.4 or in software such as 
mplayer. I have tracked down this regression between 2008-08-08 and 2008-08-09. 
That corresponds to the addition of plt support.

I have been able to do a simple testcase from sources, so I will attach a 
tarball containing objects from gcc 4.4 and the command to link them.
Comment 1 Aurelien Jarno 2009-05-11 14:02:30 UTC
Created attachment 3931 [details]
testcase
Comment 2 rsandifo@nildram.co.uk 2009-11-24 19:34:12 UTC
The problem is that the .debug_info section in thr-objc_gc.o references
thread_cancel.  How did you compile that file?
Comment 3 Thorsten Glaser 2010-01-01 14:37:17 UTC
Created attachment 4488 [details]
New minimal testcase

New more minimal testcase. I used an external function to make sure
gcc doesn’t optimise the store to __progname away. I didn’t use any
header files for simplicity, but do assume your libc has __progname.

user@debian-mipsel:~ $ gcc -O2 -g -Wall tc.c
/usr/bin/ld: non-dynamic relocations refer to dynamic symbol
__progname@@GLIBC_2.0
/usr/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld returned 1 exit status
1|user@debian-mipsel:~ $ gcc -O2 -g -Wall tc.c -DUSE_EXTERN
user@debian-mipsel:~ $ 

This is Debian sid (a-g d-u’d from aurel32’s qemu image):
• binutils 2.20-4
• gcc 4:4.4.2-2

From working on the autossh package, this bug did not occur
with the versions in Debian lenny.

Hope this helps.
Comment 4 rsandifo@nildram.co.uk 2010-01-16 17:26:05 UTC
Works for me with FSF versions of GCC and binutils, and the version
of GLIBC I have to hand.  Please post a self-contained testcase that
just needs a binutils build to run.  Please also post the .s files.
Comment 5 Thorsten Glaser 2010-01-23 18:03:10 UTC
Created attachment 4550 [details]
Testcase #3 (with .c .s .o/.so)

(In reply to comment #4)
> Works for me with FSF versions of GCC and binutils, and the version
> of GLIBC I have to hand.  Please post a self-contained testcase that
> just needs a binutils build to run.  Please also post the .s files.

Okay:

root@debian-mipsel:~ # gcc -O2 -g -S ya.c
root@debian-mipsel:~ # gcc -O2 -g -c 
ya.s									   
root@debian-mipsel:~ # gcc -O2 -g -S -fPIC yb.c
root@debian-mipsel:~ # gcc -O2 -g -fPIC -shared -o libb.so 
yb.s						     
root@debian-mipsel:~ # gcc -O2 -g -o y ya.o -L. -lb; echo =\> $?
/usr/bin/ld: non-dynamic relocations refer to dynamic symbol xxprogname
/usr/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld returned 1 exit status
=> 1


Took me a while though. The “-g” is important.

root@debian-mipsel:~ # gcc -v
Using built-in specs.
Target: mipsel-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.2-9' --with-

bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-
languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-
multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --
without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/
include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --
enable-libstdcxx-debug --disable-libssp --enable-targets=all --enable-
checking=release --build=mipsel-linux-gnu --host=mipsel-linux-gnu --
target=mipsel-linux-gnu
Thread model: posix
gcc version 4.4.3 20100108 (prerelease) (Debian 4.4.2-9) 
root@debian-mipsel:~ # ld -v
GNU ld (GNU Binutils for Debian) 2.20

binutils	2.20-5
gcc-4.4 4.4.2-9
Comment 6 Ryan Mansfield 2010-02-26 21:52:06 UTC
I believe this issue should be resolved by:

http://gcc.gnu.org/ml/gcc-patches/2009-09/msg02070.html
Comment 7 Aurelien Jarno 2010-08-23 18:43:24 UTC
This is indeed a gcc issue, marking the bug on ld as invalid.
Comment 8 Aurelien Jarno 2010-09-14 19:17:59 UTC
I am reopening the bug as it appeared that the issue is not fixed in GCC 4.5 as 
I wrongly said here. It's just that our gcc was configured to default to -mplt 
which, in some cases, workaround the issue.

To summarize the issue:
- The issue is reproducible with any gcc version (tested 4.1, 4.3, 4.4, 4.5), 
provided that you use a binutils from after 2008-08-09. binutils from before 
2008-08-08 works find with the same versions of gcc.
- The issue can always be workarounded by not using -g
- The issue can sometimes be workarounded by using -mplt
- The issue is not fixed in HEAD as of 2010-09-14.
Comment 9 Aurelien Jarno 2010-09-14 19:24:18 UTC
Created attachment 4981 [details]
Testcase with C code and makefile

This new testcase doesn't obsolete the previous ones, but it's probably more
handy as it contains the C code and a Makefile
Comment 10 Maciej W. Rozycki 2010-09-14 21:16:32 UTC
Aurelien,

 Coincidentally, I've been working on this problem for the last couple
of days.  I believe I have a fix ready that I plan to submit once it's
gone through testing; probably even tonight.

 BTW, it's enough to pass "-z nocopyreloc" to LD to make this problem
happen, regardless of GCC or GAS options used.

  Maciej
Comment 11 Aurelien Jarno 2010-09-14 23:01:30 UTC
Thanks for working on that. I have also spend some time trying to understand 
the problem. I have also written a patch by analysing the difference with other 
architecture, so I am not really sure it is correct:

--- a/elfxx-mips.c
+++ b/elfxx-mips.c
@@ -8341,6 +8339,11 @@ _bfd_mips_elf_adjust_dynamic_symbol (str
   if (h->def_regular)
     return TRUE;

+  /* If there are no references to this symbol that do not use the
+     GOT, we don't need to generate a copy reloc.  */
+  if (!h->non_got_ref)
+    return TRUE;
+
   /* There's also nothing more to do if we'll convert all relocations
      against this symbol into dynamic relocations.  */
   if (!hmips->has_static_relocs)

At least it fixes the issue.
Comment 12 Maciej W. Rozycki 2010-09-14 23:38:24 UTC
Aurelien,

 I have posted my proposal now, including LD testsuite cases:

http://sourceware.org/ml/binutils/2010-09/msg00216.html

  Maciej
Comment 13 Aurelien Jarno 2010-09-14 23:53:34 UTC
Thanks a lot for your work. I'll test it tomorrow on a few of the cases we have 
and keep you updated.
Comment 14 Aurelien Jarno 2010-09-15 05:37:31 UTC
I have built binutils including the patch linked in the previous comment. I
confirm it fixes all the problem we currently have wrt this issue. Thanks.
Comment 15 Maciej W. Rozycki 2010-11-04 18:09:18 UTC
 The fix for this issue will be included in the upcoming 2.21 release.
Comment 16 Sourceware Commits 2011-11-29 12:42:14 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	macro@sourceware.org	2011-11-29 12:42:10

Modified files:
	ld/testsuite   : ChangeLog 
	ld/testsuite/lib: ld-lib.exp 
Added files:
	ld/testsuite/ld-elf: comm-data.exp comm-data1.s comm-data1.sd 
	                     comm-data2.rd comm-data2.s comm-data2.sd 
	                     comm-data2.xd 
	ld/testsuite/ld-mips-elf: comm-data.exp 

Log message:
	PR ld/10144
	* lib/ld-lib.exp (run_ld_link_tests): Handle sources from other
	directories.
	(run_ld_link_exec_tests): Likewise.
	(run_cc_link_tests): Likewise.
	* ld-elf/comm-data1.sd: New test.
	* ld-elf/comm-data1.s: Source for the new test.
	* ld-elf/comm-data2.sd: New test.
	* ld-elf/comm-data2.rd: Likewise.
	* ld-elf/comm-data2.xd: Likewise.
	* ld-elf/comm-data2.s: Source for the new tests.
	* ld-elf/comm-data.exp: New file.
	* ld-mips-elf/comm-data.exp: Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1477&r2=1.1478
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/comm-data.exp.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/comm-data1.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/comm-data1.sd.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/comm-data2.rd.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/comm-data2.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/comm-data2.sd.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/comm-data2.xd.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-mips-elf/comm-data.exp.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/lib/ld-lib.exp.diff?cvsroot=src&r1=1.87&r2=1.88