summaryrefslogtreecommitdiffstats
path: root/binutils-2.22/bfd/elflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils-2.22/bfd/elflink.c')
-rw-r--r--binutils-2.22/bfd/elflink.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/binutils-2.22/bfd/elflink.c b/binutils-2.22/bfd/elflink.c
index fc4266b..1c5abd4 100644
--- a/binutils-2.22/bfd/elflink.c
+++ b/binutils-2.22/bfd/elflink.c
@@ -11577,6 +11577,13 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
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;
+ /* If this symbol is weak and there is a non-weak definition, we
+ keep the non-weak definition because many backends put
+ dynamic reloc info on the non-weak definition for code
+ handling copy relocs. */
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
}
@@ -11724,14 +11731,21 @@ 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))
+ if (!h->mark
+ && (((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && !(h->def_regular
+ && 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);
+ h->def_regular = 0;
+ h->ref_regular = 0;
+ h->ref_regular_nonweak = 0;
}
return TRUE;