Bug 13244 - GNU LD incorrectly complain about undefined hidden symbols with LTO
Summary: GNU LD incorrectly complain about undefined hidden symbols with LTO
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL: http://sourceware.org/ml/binutils/201...
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-01 13:10 UTC by Jan Hubicka
Modified: 2011-10-25 03:23 UTC (History)
1 user (show)

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


Attachments
Mozilla source file that produces the UNDEF load. (25.46 KB, application/octet-stream)
2011-10-01 13:10 UTC, Jan Hubicka
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Hubicka 2011-10-01 13:10:21 UTC
Created attachment 5957 [details]
Mozilla source file that produces the UNDEF load.

Mozilla does not link with GNU LD with the following error:

/abuild/jh/trunk-install/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../x86_64-unknown-linux-gnu/bin/ld:                                                                        
libxul.so: hidden symbol `_mm_load_si128' isn't defined                                                                                                                             
/abuild/jh/trunk-install/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../x86_64-unknown-linux-gnu/bin/ld:                                                                        
final link failed: Bad value                                                                                                                                                        

What happens is approximately the following:

1) _mm_load_si128 is extern inline function that is assumed to be always inlined and thus it has no non-extern inline definition in the whole DSO.  It is also always inline, so it is OK.
2) GCC delays removal of extern inlines and virtual functions from callgraph until after IPA inlining. This is in order to increase chances that they will be inlined when their call is discovered later via devirtualization or when address is taken
3) Symbol streaming outputs the symbols based at calgraph. Even though the function was fully inlined, the kept external body makes it to output use of _mm_load_si128 symbol
4) In resolution table we get:
974 314cd963 UNDEF _mm_load_si128  
but the refrence to _mm_load_si28 is optimized out at linktime.

The linker ought to not complain about the hidden symbol reference that has been optimized out. At least gold behaves this way.

I am going to fix 3) at GCC side, but se still ought not to complain at 4).

Honza
Comment 1 H.J. Lu 2011-10-05 21:29:59 UTC
Please provide complete command line used to reproduce this.
Comment 2 hubicka 2011-10-06 18:45:42 UTC
jh@evans:/abuild/jh/trunk-3/build-inst7/gcc> cat t.c
extern __attribute__ ((visibility("hidden"))) int fooblah;

static
do_nothing (int param)
{ 
  if (param)
   fooblah = 1;
}

main()
{ 
  do_nothing (0);
}
jh@evans:/abuild/jh/trunk-3/build-inst7/gcc> ./xgcc -B ./ -O2 t.c  -fno-early-inlining -flto -fuse-linker-plugin
jh@evans:/abuild/jh/trunk-3/build-inst7/gcc> ./xgcc -B ./ -O2 t.c  -fno-early-inlining -flto -fuse-linker-plugin --shared
/abuild/jh/trunk-install/x86_64-unknown-linux-gnu/bin/ld: a.out: hidden symbol `fooblah' isn't defined
/abuild/jh/trunk-install/x86_64-unknown-linux-gnu/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

With gold I get:
jh@evans:/abuild/jh/trunk-3/build-inst7/gcc> ./xgcc -B ./ -O2 t.c  -fno-early-inlining -flto -fuse-linker-plugin --shared
jh@evans:/abuild/jh/trunk-3/build-inst7/gcc> 

because fooblah gets optimized out.

Honza
Comment 3 H.J. Lu 2011-10-06 23:29:18 UTC
This works for me:

---
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 7120aad..0d216c2 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8691,7 +8691,7 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
 	    || h->root.type == bfd_link_hash_undefweak)
 	   && h->root.u.undef.abfd != NULL
 	   && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0)
-    strip = TRUE;
+    return TRUE;
   else
     strip = FALSE;
 
---
Comment 4 H.J. Lu 2011-10-07 16:48:13 UTC
A patch is posted at

http://sourceware.org/ml/binutils/2011-10/msg00034.html
Comment 5 cvs-commit@gcc.gnu.org 2011-10-08 07:50:25 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2011-10-08 07:50:19

Modified files:
	bfd            : ChangeLog elflink.c 

Log message:
	PR ld/13229
	PR ld/13244
	* elflink.c (elf_link_add_object_symbols): Don't make IR symbols
	dynamic.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5482&r2=1.5483
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.423&r2=1.424
Comment 6 Alan Modra 2011-10-08 07:56:42 UTC
I believe the bug is now fixed but I'll leave closing it to Jan.
Comment 7 cvs-commit@gcc.gnu.org 2011-10-25 02:54:29 UTC
CVSROOT:	/cvs/src
Module name:	src
Branch: 	binutils-2_22-branch
Changes by:	amodra@sourceware.org	2011-10-25 02:54:25

Modified files:
	bfd            : ChangeLog elflink.c 

Log message:
	PR ld/13229
	PR ld/13244
	Apply mainline patches
	2011-10-08  Alan Modra  <amodra@gmail.com>
	* elflink.c (elf_link_add_object_symbols): Don't make IR symbols
	dynamic.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&only_with_tag=binutils-2_22-branch&r1=1.5473.2.9&r2=1.5473.2.10
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&only_with_tag=binutils-2_22-branch&r1=1.420.2.4&r2=1.420.2.5
Comment 8 Alan Modra 2011-10-25 03:23:03 UTC
Fixed