diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 4 | ||||
-rw-r--r-- | bfd/elflink.c | 21 |
3 files changed, 22 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4276dd8..062d9e4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,11 @@ 2005-07-26 Alan Modra <amodra@bigpond.net.au> + * elflink.c (elf_gc_mark_dynamic_ref_symbol): Handle -shared. + (bfd_elf_gc_sections): Allow -gc-sections when -shared. + * elf32-ppc.c (ppc_elf_gc_sweep_hook): Correct for -shared. + +2005-07-26 Alan Modra <amodra@bigpond.net.au> + * elflink.c (elf_gc_sweep): Move gcc_except_table code.. (bfd_elf_gc_sections): ..to here. diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 16d11c4..58afcda 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -3728,8 +3728,12 @@ ppc_elf_gc_sweep_hook (bfd *abfd, case R_PPC_ADDR14_BRNTAKEN: case R_PPC_UADDR32: case R_PPC_UADDR16: + if (info->shared) + break; + case R_PPC_PLT32: case R_PPC_PLTREL24: + case R_PPC_PLTREL32: case R_PPC_PLT16_LO: case R_PPC_PLT16_HI: case R_PPC_PLT16_HA: diff --git a/bfd/elflink.c b/bfd/elflink.c index 067ac3b..102b895 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -9072,19 +9072,25 @@ elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp) return TRUE; } -/* Mark sections containing dynamically referenced symbols. This is called - through elf_link_hash_traverse. */ +/* Mark sections containing dynamically referenced symbols. When + building shared libraries, we must assume that any visible symbol is + referenced. */ static bfd_boolean -elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, - void *okp ATTRIBUTE_UNUSED) +elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf) { + struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; if ((h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) - && h->ref_dynamic) + && (h->ref_dynamic + || (info->shared + && h->def_regular + && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL + && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN))) h->root.u.def.section->flags |= SEC_KEEP; return TRUE; @@ -9104,7 +9110,6 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) if (!get_elf_backend_data (abfd)->can_gc_sections || info->relocatable || info->emitrelocations - || info->shared || !is_elf_hash_table (info->hash)) { (*_bfd_error_handler)(_("Warning: gc-sections option ignored")); @@ -9129,9 +9134,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) if (elf_hash_table (info)->dynamic_sections_created) elf_link_hash_traverse (elf_hash_table (info), elf_gc_mark_dynamic_ref_symbol, - &ok); - if (!ok) - return FALSE; + info); /* Grovel through relocs to find out who stays ... */ gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook; |