This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: PR ld/13177: garbage collector retains zombie references to external libraries


HJ,
  Your patch for PR13177 causes
hppa-linux  +FAIL: --gc-sections with __start_
mips64-linux  +FAIL: --gc-sections with __start_
mipsel-linux-gnu  +FAIL: --gc-sections with __start_
mipsisa32el-linux  +FAIL: --gc-sections with __start_
mips-linux  +FAIL: --gc-sections with __start_
powerpc64-linux  +FAIL: --gc-sections with __start_

The failures show up because __start__foo is undefined when
lang_gc_sections runs (the symbol is defined later in
lang_place_orphans).  This exposes an error in the way you treat
undefined symbols.  Not all ABIs require an undefined symbol reference
to generate a PLT entry.  You only need one when there is a function
call, or when the address of a function is taken and the ABI defines
the address to be the PLT entry in the executable
(ptr_equality_needed case).  So it is quite reasonable for
__start__foo to have a plt.refcount of zero in elf_gc_sweep_symbol.

I'm testing the following.

	PR ld/13177
	* 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.
	(elf_link_output_extsym): Correct test for warning when forced local
	executable syms are referenced from shared libraries.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.425
diff -u -p -r1.425 elflink.c
--- bfd/elflink.c	8 Oct 2011 16:51:09 -0000	1.425
+++ bfd/elflink.c	17 Oct 2011 07:08:58 -0000
@@ -8659,10 +8659,11 @@ elf_link_output_extsym (struct bfd_hash_
 
   /* We should also warn if a forced local symbol is referenced from
      shared libraries.  */
-  if (! finfo->info->relocatable
-      && (! finfo->info->shared)
+  if (!finfo->info->relocatable
+      && finfo->info->executable
       && h->forced_local
       && h->ref_dynamic
+      && h->def_regular
       && !h->dynamic_def
       && !h->dynamic_weak
       && ! elf_link_check_versioned_symbol (finfo->info, bed, h))
@@ -11571,6 +11577,7 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_i
       while (h->root.type == bfd_link_hash_indirect
 	     || h->root.type == bfd_link_hash_warning)
 	h = (struct elf_link_hash_entry *) h->root.u.i.link;
+      h->mark = 1;
       return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
     }
 
@@ -11718,18 +11725,16 @@ struct elf_gc_sweep_symbol_info
 static bfd_boolean
 elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
 {
-  if (((h->root.type == bfd_link_hash_defined
-	|| h->root.type == bfd_link_hash_defweak)
-       && !h->root.u.def.section->gc_mark
-       && (!(h->root.u.def.section->owner->flags & DYNAMIC)
-	   || (h->plt.refcount <= 0
-	       && h->got.refcount <= 0)))
-      || (h->root.type == bfd_link_hash_undefined
-	  && h->plt.refcount <= 0
-	  && h->got.refcount <= 0))
+  if (!h->mark
+      && (((h->root.type == bfd_link_hash_defined
+	    || h->root.type == bfd_link_hash_defweak)
+	   && !h->root.u.def.section->gc_mark)
+	  || h->root.type == bfd_link_hash_undefined
+	  || h->root.type == bfd_link_hash_undefweak))
     {
-      struct elf_gc_sweep_symbol_info *inf =
-	(struct elf_gc_sweep_symbol_info *) data;
+      struct elf_gc_sweep_symbol_info *inf;
+
+      inf = (struct elf_gc_sweep_symbol_info *) data;
       (*inf->hide_symbol) (inf->info, h, TRUE);
     }
 


-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]