Bug 12366 - assertion failure with STT_GNU_IFUNC symbols on x86_64
Summary: assertion failure with STT_GNU_IFUNC symbols on x86_64
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
: 12801 12819 12838 (view as bug list)
Depends on:
Blocks: 12372 12801
  Show dependency treegraph
 
Reported: 2011-01-05 16:42 UTC by Richard Sandiford (Linaro)
Modified: 2011-06-03 20:30 UTC (History)
5 users (show)

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


Attachments
Shell script to reproduce bug (260 bytes, application/x-shellscript)
2011-01-05 16:42 UTC, Richard Sandiford (Linaro)
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Sandiford (Linaro) 2011-01-05 16:42:16 UTC
Created attachment 5181 [details]
Shell script to reproduce bug

The x86 and x86_64 IFUNC code assumes that check_relocs can rely on def_regular being set for all regular definitions.  That's not true, because def_regular is set by the same pass that calls check_relocs, and doesn't therefore take into account regular definitions in later objects.  Everything works if the regular definition comes before the regular use, but not the other way round.

I've attached a simple example.  The link order in the example gives:

./ld/ld-new: BFD (GNU Binutils) 2.21.51.20110105 internal error, aborting at /usr/export/richards-desktop-2/richards/binutils/HEAD/src/bfd/elf64-x86-64.c line 2802 in elf_x86_64_relocate_section

./ld/ld-new: Please report this bug.

But linking bar.o before foo.o works as expected.
Comment 1 Sourceware Commits 2011-01-06 18:45:09 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl@sourceware.org	2011-01-06 18:45:05

Modified files:
	bfd            : ChangeLog elf-ifunc.c elf32-i386.c 
	                 elf64-x86-64.c 
	ld/testsuite   : ChangeLog 
	ld/testsuite/ld-ifunc: ifunc-10-i386.s ifunc-10-x86-64.s 
	                       ifunc-11-i386.s ifunc-11-x86-64.s 
Added files:
	ld/testsuite/ld-ifunc: ifunc-12-i386.d ifunc-12-i386.s 
	                       ifunc-12-x86-64.d ifunc-12-x86-64.s 
	                       ifunc-13-i386.d ifunc-13-x86-64.d 
	                       ifunc-13a-i386.s ifunc-13a-x86-64.s 
	                       ifunc-13b-i386.s ifunc-13b-x86-64.s 

Log message:
	Handle STT_GNU_IFUNC symols when building shared library.
	
	bfd/
	
	2012-01-06  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/12366
	PR ld/12371
	* elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Properly
	handle symbols marked with regular reference, but not non-GOT
	reference when building shared library.
	
	* elf32-i386.c (elf_i386_gc_sweep_hook): Properly handle
	local and global STT_GNU_IFUNC symols when building shared
	library.
	* elf64-x86-64.c (elf_x86_64_gc_sweep_hook): Likewise.
	
	ld/testsuite/
	
	2012-01-06  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/12366
	PR ld/12371
	* ld-ifunc/ifunc-10-i386.s: Add more tests.
	* ld-ifunc/ifunc-10-x86-64.s: Likewise.
	* ld-ifunc/ifunc-11-i386.s: Likewise.
	* ld-ifunc/ifunc-11-x86-64.s: Likewise.
	
	* ld-ifunc/ifunc-12-i386.d: New.
	* ld-ifunc/ifunc-12-i386.s: Likewise.
	* ld-ifunc/ifunc-12-x86-64.d: Likewise.
	* ld-ifunc/ifunc-12-x86-64.s: Likewise.
	* ld-ifunc/ifunc-13-i386.d: Likewise.
	* ld-ifunc/ifunc-13-x86-64.d: Likewise.
	* ld-ifunc/ifunc-13a-i386.s: Likewise.
	* ld-ifunc/ifunc-13a-x86-64.s: Likewise.
	* ld-ifunc/ifunc-13b-i386.s: Likewise.
	* ld-ifunc/ifunc-13b-x86-64.s: Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5223&r2=1.5224
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf-ifunc.c.diff?cvsroot=src&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-i386.c.diff?cvsroot=src&r1=1.241&r2=1.242
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-x86-64.c.diff?cvsroot=src&r1=1.204&r2=1.205
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1348&r2=1.1349
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-12-i386.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-12-i386.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-12-x86-64.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-12-x86-64.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13-i386.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13-x86-64.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13a-i386.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13a-x86-64.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13b-i386.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13b-x86-64.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-10-i386.s.diff?cvsroot=src&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-10-x86-64.s.diff?cvsroot=src&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-11-i386.s.diff?cvsroot=src&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-11-x86-64.s.diff?cvsroot=src&r1=1.1&r2=1.2
Comment 2 H.J. Lu 2011-01-06 18:48:15 UTC
Fixed.
Comment 3 H.J. Lu 2011-01-07 02:06:39 UTC
(In reply to comment #0)
> Created attachment 5181 [details]
> Shell script to reproduce bug
> 
> The x86 and x86_64 IFUNC code assumes that check_relocs can rely on def_regular
> being set for all regular definitions.  That's not true, because def_regular is
> set by the same pass that calls check_relocs, and doesn't therefore take into
> account regular definitions in later objects.

We handle relocations against local STT_GNU_IFUNC symbols by
faking a STT_GNU_IFUNC symbol. def_regular is true for
those symbols.

My fix in _bfd_elf_allocate_ifunc_dyn_relocs handles
the case where a symbol is marked with regular reference,
but not non-GOT reference.  It may happen if we didn't
see STT_GNU_IFUNC symbol when checking relocations.
Comment 4 Ian Lance Taylor 2011-05-25 15:26:51 UTC
Seems like this patch should be ported to the 2.21 branch.
Comment 5 H.J. Lu 2011-05-25 15:36:11 UTC
*** Bug 12801 has been marked as a duplicate of this bug. ***
Comment 6 Sourceware Commits 2011-05-25 17:41:40 UTC
CVSROOT:	/cvs/src
Module name:	src
Branch: 	binutils-2_21-branch
Changes by:	hjl@sourceware.org	2011-05-25 17:41:35

Modified files:
	ld/testsuite   : ChangeLog 
	ld/testsuite/ld-ifunc: ifunc-10-i386.s ifunc-10-x86-64.s 
	                       ifunc-11-i386.s ifunc-11-x86-64.s 
	bfd            : ChangeLog elf-ifunc.c elf32-i386.c 
	                 elf64-x86-64.c 
Added files:
	ld/testsuite/ld-ifunc: ifunc-12-i386.d ifunc-12-i386.s 
	                       ifunc-12-x86-64.d ifunc-12-x86-64.s 
	                       ifunc-13-i386.d ifunc-13-x86-64.d 
	                       ifunc-13a-i386.s ifunc-13a-x86-64.s 
	                       ifunc-13b-i386.s ifunc-13b-x86-64.s 

Log message:
	Handle STT_GNU_IFUNC symols when building shared library.
	
	bfd/
	
	2012-05-25  H.J. Lu  <hongjiu.lu@intel.com>
	
	Backport from mainline
	2012-01-06  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/12366
	PR ld/12371
	* elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Properly
	handle symbols marked with regular reference, but not non-GOT
	reference when building shared library.
	
	* elf32-i386.c (elf_i386_gc_sweep_hook): Properly handle
	local and global STT_GNU_IFUNC symols when building shared
	library.
	* elf64-x86-64.c (elf_x86_64_gc_sweep_hook): Likewise.
	
	ld/testsuite/
	
	2012-05-25  H.J. Lu  <hongjiu.lu@intel.com>
	
	Backport from mainline
	2012-01-06  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/12366
	PR ld/12371
	* ld-ifunc/ifunc-10-i386.s: Add more tests.
	* ld-ifunc/ifunc-10-x86-64.s: Likewise.
	* ld-ifunc/ifunc-11-i386.s: Likewise.
	* ld-ifunc/ifunc-11-x86-64.s: Likewise.
	
	* ld-ifunc/ifunc-12-i386.d: New.
	* ld-ifunc/ifunc-12-i386.s: Likewise.
	* ld-ifunc/ifunc-12-x86-64.d: Likewise.
	* ld-ifunc/ifunc-12-x86-64.s: Likewise.
	* ld-ifunc/ifunc-13-i386.d: Likewise.
	* ld-ifunc/ifunc-13-x86-64.d: Likewise.
	* ld-ifunc/ifunc-13a-i386.s: Likewise.
	* ld-ifunc/ifunc-13a-x86-64.s: Likewise.
	* ld-ifunc/ifunc-13b-i386.s: Likewise.
	* ld-ifunc/ifunc-13b-x86-64.s: Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.1322.2.11&r2=1.1322.2.12
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-12-i386.d.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-12-i386.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-12-x86-64.d.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-12-x86-64.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13-i386.d.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13-x86-64.d.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13a-i386.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13a-x86-64.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13b-i386.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-13b-x86-64.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-10-i386.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-10-x86-64.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-11-i386.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-11-x86-64.s.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.5180.2.33&r2=1.5180.2.34
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf-ifunc.c.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.4&r2=1.4.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-i386.c.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.241.2.1&r2=1.241.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-x86-64.c.diff?cvsroot=src&only_with_tag=binutils-2_21-branch&r1=1.202.2.1&r2=1.202.2.2
Comment 7 H.J. Lu 2011-05-28 00:48:36 UTC
*** Bug 12819 has been marked as a duplicate of this bug. ***
Comment 8 H.J. Lu 2011-06-03 14:49:45 UTC
*** Bug 12838 has been marked as a duplicate of this bug. ***
Comment 9 Guido Trentalancia 2011-06-03 20:30:23 UTC
The ChangeLog diffs do not apply cleanly to the current 2.21 release.

The rest applies cleanly and apparently it also fixes the issue which was occurring while building glibc 2.14