This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: PR ld/13177: garbage collector retains zombie references to external libraries
- From: Alan Modra <amodra at gmail dot com>
- To: "H.J. Lu" <hjl dot tools at gmail dot com>, binutils at sourceware dot org
- Date: Mon, 17 Oct 2011 17:58:48 +1030
- Subject: Re: PATCH: PR ld/13177: garbage collector retains zombie references to external libraries
- References: <20110914191438.GA4795@intel.com> <20110915002501.GM10321@bubble.grove.modra.org> <CAMe9rOo0ADerLbtb6=J4KWS8LvtGhWnKy66vEQfcnsRZ08x+gw@mail.gmail.com> <20110916005216.GP10321@bubble.grove.modra.org>
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