Bug 13177 - garbage collector retains zombie references to external libraries
Summary: garbage collector retains zombie references to external libraries
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL: http://sourceware.org/ml/binutils/201...
Keywords:
Depends on:
Blocks: 13232
  Show dependency treegraph
 
Reported: 2011-09-11 08:41 UTC by Rene
Modified: 2017-01-18 18:47 UTC (History)
2 users (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rene 2011-09-11 08:41:31 UTC
If shared library is compiled and linked with garbage collection enabled,
zombie references to external libraries are retained that result future link failure.
(ld 2.21, gcc 4.5.2, Ubuntu 11.04)

Steps to repro:
* Create file shared.c
--8<--
#include <dlfcn.h>
void opt_out(const char *name)
{
	dlopen(name, RTLD_LAZY);
}
__attribute__ ((visibility ("default"))) int add_two(int number)
{
	return number+2;
}
-->8--

* Create shared library by running
gcc -fpic -shared -ffunction-sections -fdata-sections -Wl,--gc-sections -fvisibility=hidden -o libtest.so shared.c -static-libgcc
Result: SUCCESS, no errors.

* Verify created library references by running
ldd -r libtest.so
Resukt: SUCCESS. No unreferenced symbols and expected list of library bindings.

* Create file main.c:
--8<--
int add_two(int);
int main()
{
	return add_two(-2);
}
-->8--

* Create a program by running:
gcc -o main main.c -L. -ltest
Expected result: Program compailes and links correctly.
Acttual result: FAIL. ld returns:
  ./libtest.so: undefined reference to 'dlopen' 
  collect2: ld returned 1 exit status
Comment 1 H.J. Lu 2011-09-14 19:15:38 UTC
A patch is posted at

http://sourceware.org/ml/binutils/2011-09/msg00076.html
Comment 2 cvs-commit@gcc.gnu.org 2011-09-16 01:17:19 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl@sourceware.org	2011-09-16 01:17:16

Modified files:
	ld/testsuite   : ChangeLog 
	bfd            : ChangeLog elflink.c 
Added files:
	ld/testsuite/ld-elf: pr13177.d pr13177.s 

Log message:
	Also hide symbols without PLT nor GOT references.
	
	bfd/
	
	2011-09-15  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/13177
	* elflink.c (elf_gc_sweep_symbol): Also hide symbols without PLT
	nor GOT references.
	
	ld/testsuite/
	
	2011-09-15  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/13177
	* ld-elf/pr13177.d: New.
	* ld-elf/pr13177.s: Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1458&r2=1.1459
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/pr13177.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/pr13177.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5470&r2=1.5471
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.419&r2=1.420
Comment 3 H.J. Lu 2011-09-16 04:25:18 UTC
Fixed.
Comment 5 H.J. Lu 2011-10-18 19:08:03 UTC
Patch is reverted on 2.22 branch,
Comment 6 cvs-commit@gcc.gnu.org 2011-10-19 07:17:27 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2011-10-19 07:17:21

Modified files:
	bfd            : ChangeLog elf32-arm.c elf32-bfin.c elf32-cris.c 
	                 elf32-frv.c elf32-i386.c elf32-m32r.c 
	                 elf32-m68k.c elf32-ppc.c elf32-s390.c 
	                 elf32-sh.c elf32-spu.c elf32-tilepro.c 
	                 elf32-xtensa.c elf64-alpha.c elf64-ppc.c 
	                 elf64-s390.c elf64-sh64.c elf64-x86-64.c 
	                 elflink.c elf-m10300.c elfxx-sparc.c 
	                 elfxx-tilegx.c 
	ld/testsuite   : ChangeLog 
	ld/testsuite/ld-elf: elf.exp 
	ld/testsuite/ld-gc: gc.exp 
	ld/testsuite/lib: ld-lib.exp 
Added files:
	ld/testsuite/ld-gc: libpersonality.s personality.d personality.s 

Log message:
	PR ld/13177
	bfd/
	* elflink.c (_bfd_elf_gc_mark_rsec): Set symbol "mark".
	(elf_gc_sweep_symbol): Don't test plt/got refcounts, instead test
	"mark".  Hide undefweak too.  Clear def_regular and ref_regular.
	* elf-m10300.c (mn10300_elf_relocate_section): Ignore unresolved
	reloc errors from garbage-collected code.
	* elf32-arm.c (elf32_arm_relocate_section): Likewise.
	* elf32-bfin.c (bfin_relocate_section): Likewise.
	(bfinfdpic_relocate_section): Likewise.
	* elf32-cris.c (cris_elf_relocate_section): Likewise.
	* elf32-frv.c (elf32_frv_relocate_section): Likewise.
	* elf32-i386.c (elf_i386_relocate_section): Likewise.
	* elf32-m32r.c (m32r_elf_relocate_section): Likewise.
	* elf32-m68k.c (elf_m68k_relocate_section): Likewise.
	* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
	* elf32-s390.c (elf_s390_relocate_section): Likewise.
	* elf32-sh.c (sh_elf_relocate_section): Likewise.
	* elf32-spu.c (spu_elf_relocate_section): Likewise.
	* elf32-tilepro.c (tilepro_elf_relocate_section): Likewise.
	* elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
	* elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
	* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
	* elf64-s390.c (elf_s390_relocate_section): Likewise.
	* elf64-sh64.c (sh_elf64_relocate_section): Likewise.
	* elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
	* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
	* elfxx-tilegx.c (tilegx_elf_relocate_section): Likewise.
	ld/testsuite/
	* ld-elf/elf.exp: Move test for shared lib support..
	* lib/ld-lib.exp (check_shared_lib_support): ..to here. Add m68hc1*,
	and s/ms1/mt/.
	(check_gc_sections_available): Match hppa*64 not hppa64.  Comment.
	* ld-gc/libpersonality.s: New.
	* ld-gc/personality.s, * ld-gc/personality.d: New.
	* ld-gc/gc.exp: Run personality test.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5494&r2=1.5495
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-arm.c.diff?cvsroot=src&r1=1.277&r2=1.278
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-bfin.c.diff?cvsroot=src&r1=1.54&r2=1.55
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-cris.c.diff?cvsroot=src&r1=1.116&r2=1.117
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-frv.c.diff?cvsroot=src&r1=1.73&r2=1.74
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-i386.c.diff?cvsroot=src&r1=1.260&r2=1.261
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-m32r.c.diff?cvsroot=src&r1=1.102&r2=1.103
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-m68k.c.diff?cvsroot=src&r1=1.126&r2=1.127
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-ppc.c.diff?cvsroot=src&r1=1.302&r2=1.303
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-s390.c.diff?cvsroot=src&r1=1.108&r2=1.109
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-sh.c.diff?cvsroot=src&r1=1.172&r2=1.173
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-spu.c.diff?cvsroot=src&r1=1.101&r2=1.102
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-tilepro.c.diff?cvsroot=src&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-xtensa.c.diff?cvsroot=src&r1=1.130&r2=1.131
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-alpha.c.diff?cvsroot=src&r1=1.181&r2=1.182
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-ppc.c.diff?cvsroot=src&r1=1.366&r2=1.367
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-s390.c.diff?cvsroot=src&r1=1.108&r2=1.109
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-sh64.c.diff?cvsroot=src&r1=1.87&r2=1.88
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-x86-64.c.diff?cvsroot=src&r1=1.239&r2=1.240
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.427&r2=1.428
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf-m10300.c.diff?cvsroot=src&r1=1.108&r2=1.109
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elfxx-sparc.c.diff?cvsroot=src&r1=1.61&r2=1.62
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elfxx-tilegx.c.diff?cvsroot=src&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1470&r2=1.1471
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/elf.exp.diff?cvsroot=src&r1=1.30&r2=1.31
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-gc/libpersonality.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-gc/personality.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-gc/personality.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-gc/gc.exp.diff?cvsroot=src&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/lib/ld-lib.exp.diff?cvsroot=src&r1=1.85&r2=1.86
Comment 7 Alan Modra 2012-02-22 03:35:16 UTC
Fixed mainline
Comment 8 Jackie Rosen 2014-02-16 19:40:39 UTC Comment hidden (spam)
Comment 9 cvs-commit@gcc.gnu.org 2017-01-18 18:32:26 UTC
The master branch has been updated by Maciej W. Rozycki <macro@sourceware.org>:

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

commit 81ff47b3a54633819fac4d973e34f1ff0c65606e
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Mon Jan 16 22:10:57 2017 +0000

    PR ld/20828: Fix linker script symbols wrongly forced local with section GC
    
    Fix a generic ELF linker regression introduced with a chain of changes
    made to unused input section garbage collection:
    
    - commit 1a766c6843ce ("Also hide symbols without PLT nor GOT
      references."),
      <https://sourceware.org/ml/binutils/2011-09/msg00076.html>,
    
    - commit 1d5316ab67e1 ("PR ld/13177: garbage collector retains zombie
      references to external libraries"),
      <https://sourceware.org/ml/binutils/2011-10/msg00161.html>,
    
    - commit 6673f753c019 ("Fix PR 12772, garbage collection of dynamic
      syms"), <https://sourceware.org/ml/binutils/2011-12/msg00077.html>,
    
    causing the garbage collection of unused symbols present in a DSO
    involved in a link to make identically named symbols ordinarily defined
    (i.e. not hidden or PROVIDEd) by a linker script local, even though the
    latter symbols are supposed to be global as if no DSO defined them as
    well.
    
    This is because linker script assignments are processed very late as
    `lang_process' proceeds, down in the call to `ldemul_before_allocation',
    which is made after the call to `lang_gc_sections' to do input section
    garbage collecting.  Consequently if unused, then any such DSO-defined
    symbol has already been garbage-collected and internally marked local.
    It would ordinarily be removed from dynamic symbol table output, however
    a linker script assignment correctly replaces its original definition
    with the new one and enters it into the dynamic symbol table produced as
    it is supposed to be exported.  The original local marking is however
    retained making the symbol local in the dynamic symbol table and
    therefore not available externally.  This also causes a sorting problem
    with the MIPS target, which does not expect non-section local dynamic
    symbols to be output and produces an invalid binary.
    
    Fix the problem then, by removing the `forced_local' marking for the
    offending case and add suitable test cases.  First to verify that unused
    symbols ordinarily defined with linker script assignments remain
    exported in the context of input section garbage collection whether or
    not a DSO defining identically named symbols is present in the link.
    Second that a linker version script still correctly retains or removes
    such symbols as requested.
    
    	bfd/
    	PR ld/20828
    	* elflink.c (bfd_elf_record_link_assignment): Clear any
    	`forced_local' marking for DSO symbols that are not being
    	provided.
    
    	ld/
    	PR ld/20828
    	* testsuite/ld-elf/pr20828-1.sd: New test.
    	* testsuite/ld-elf/pr20828-2a.sd: New test.
    	* testsuite/ld-elf/pr20828-2b.sd: New test.
    	* testsuite/ld-elf/pr20828.ld: New test linker script.
    	* testsuite/ld-elf/pr20828.ver: New test version script.
    	* testsuite/ld-elf/pr20828.s: New test source.
    	* testsuite/ld-elf/shared.exp: Run the new test.
Comment 10 cvs-commit@gcc.gnu.org 2017-01-18 18:47:17 UTC
The binutils-2_28-branch branch has been updated by Maciej W. Rozycki <macro@sourceware.org>:

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

commit 4030096d6a689125c026ce1e6300717c2050d105
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Mon Jan 16 22:10:57 2017 +0000

    PR ld/20828: Fix linker script symbols wrongly forced local with section GC
    
    Fix a generic ELF linker regression introduced with a chain of changes
    made to unused input section garbage collection:
    
    - commit 1a766c6843ce ("Also hide symbols without PLT nor GOT
      references."),
      <https://sourceware.org/ml/binutils/2011-09/msg00076.html>,
    
    - commit 1d5316ab67e1 ("PR ld/13177: garbage collector retains zombie
      references to external libraries"),
      <https://sourceware.org/ml/binutils/2011-10/msg00161.html>,
    
    - commit 6673f753c019 ("Fix PR 12772, garbage collection of dynamic
      syms"), <https://sourceware.org/ml/binutils/2011-12/msg00077.html>,
    
    causing the garbage collection of unused symbols present in a DSO
    involved in a link to make identically named symbols ordinarily defined
    (i.e. not hidden or PROVIDEd) by a linker script local, even though the
    latter symbols are supposed to be global as if no DSO defined them as
    well.
    
    This is because linker script assignments are processed very late as
    `lang_process' proceeds, down in the call to `ldemul_before_allocation',
    which is made after the call to `lang_gc_sections' to do input section
    garbage collecting.  Consequently if unused, then any such DSO-defined
    symbol has already been garbage-collected and internally marked local.
    It would ordinarily be removed from dynamic symbol table output, however
    a linker script assignment correctly replaces its original definition
    with the new one and enters it into the dynamic symbol table produced as
    it is supposed to be exported.  The original local marking is however
    retained making the symbol local in the dynamic symbol table and
    therefore not available externally.  This also causes a sorting problem
    with the MIPS target, which does not expect non-section local dynamic
    symbols to be output and produces an invalid binary.
    
    Fix the problem then, by removing the `forced_local' marking for the
    offending case and add suitable test cases.  First to verify that unused
    symbols ordinarily defined with linker script assignments remain
    exported in the context of input section garbage collection whether or
    not a DSO defining identically named symbols is present in the link.
    Second that a linker version script still correctly retains or removes
    such symbols as requested.
    
    	bfd/
    	PR ld/20828
    	* elflink.c (bfd_elf_record_link_assignment): Clear any
    	`forced_local' marking for DSO symbols that are not being
    	provided.
    
    	ld/
    	PR ld/20828
    	* testsuite/ld-elf/pr20828-1.sd: New test.
    	* testsuite/ld-elf/pr20828-2a.sd: New test.
    	* testsuite/ld-elf/pr20828-2b.sd: New test.
    	* testsuite/ld-elf/pr20828.ld: New test linker script.
    	* testsuite/ld-elf/pr20828.ver: New test version script.
    	* testsuite/ld-elf/pr20828.s: New test source.
    	* testsuite/ld-elf/shared.exp: Run the new test.
    
    (cherry picked from commit 81ff47b3a54633819fac4d973e34f1ff0c65606e)