From 64d03ab565d55c20bfa7267bc669876a8fbea912 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 17 Jan 2006 15:32:41 +0000 Subject: [PATCH] * elf-bfd.h (struct elf_backend_data): Add gc_mark_dynamic_ref. (bfd_elf_gc_mark_dynamic_ref_symbol): Declare. * elflink.c (bfd_elf_gc_mark_dynamic_ref_symbol): Rename from elf_gc_mark_dynamic_ref_symbol. Make global. (bfd_elf_gc_sections): Call bed->gc_mark_dynamic_ref. * elfxx-target.h (elf_backend_gc_mark_dynamic_ref): Define. (elfNN_bed): Init new field. * elf64-ppc.c (elf_backend_gc_mark_dynamic_ref): Define. (ppc64_elf_gc_mark_dynamic_ref): New function. --- bfd/ChangeLog | 12 ++++++++++++ bfd/elf-bfd.h | 10 +++++++++- bfd/elf64-ppc.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ bfd/elflink.c | 15 +++++++------- bfd/elfxx-target.h | 6 +++++- 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index eb9e0d110bf..63925c33f46 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2006-01-18 Alan Modra + + * elf-bfd.h (struct elf_backend_data): Add gc_mark_dynamic_ref. + (bfd_elf_gc_mark_dynamic_ref_symbol): Declare. + * elflink.c (bfd_elf_gc_mark_dynamic_ref_symbol): Rename from + elf_gc_mark_dynamic_ref_symbol. Make global. + (bfd_elf_gc_sections): Call bed->gc_mark_dynamic_ref. + * elfxx-target.h (elf_backend_gc_mark_dynamic_ref): Define. + (elfNN_bed): Init new field. + * elf64-ppc.c (elf_backend_gc_mark_dynamic_ref): Define. + (ppc64_elf_gc_mark_dynamic_ref): New function. + 2006-01-17 Alan Modra * elf64-ppc.c (ppc64_elf_gc_mark_hook): Don't hang forever in loop. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 18ccdb57522..b81f440283e 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1,6 +1,6 @@ /* BFD back-end data structures for ELF files. Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -830,6 +830,11 @@ struct elf_backend_data bfd_boolean (*elf_backend_modify_segment_map) (bfd *, struct bfd_link_info *); + /* This function is called during section garbage collection to + mark sections that define global symbols. */ + bfd_boolean (*gc_mark_dynamic_ref) + (struct elf_link_hash_entry *h, void *inf); + /* This function is called during section gc to discover the section a particular relocation refers to. */ asection * (*gc_mark_hook) @@ -1808,6 +1813,9 @@ extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn extern bfd_boolean bfd_elf_final_link (bfd *, struct bfd_link_info *); +extern bfd_boolean bfd_elf_gc_mark_dynamic_ref_symbol + (struct elf_link_hash_entry *h, void *inf); + extern bfd_boolean bfd_elf_gc_sections (bfd *, struct bfd_link_info *); diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 501d4b7f87d..3a807ebb27c 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -89,6 +89,7 @@ static bfd_vma opd_entry_value #define elf_backend_check_directives ppc64_elf_check_directives #define elf_backend_archive_symbol_lookup ppc64_elf_archive_symbol_lookup #define elf_backend_check_relocs ppc64_elf_check_relocs +#define elf_backend_gc_mark_dynamic_ref ppc64_elf_gc_mark_dynamic_ref #define elf_backend_gc_mark_hook ppc64_elf_gc_mark_hook #define elf_backend_gc_sweep_hook ppc64_elf_gc_sweep_hook #define elf_backend_adjust_dynamic_symbol ppc64_elf_adjust_dynamic_symbol @@ -4939,6 +4940,54 @@ opd_entry_value (asection *opd_sec, return val; } +/* Mark sections containing dynamically referenced symbols. When + building shared libraries, we must assume that any visible symbol is + referenced. */ + +static bfd_boolean +ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf) +{ + struct bfd_link_info *info = (struct bfd_link_info *) inf; + struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h; + + if (eh->elf.root.type == bfd_link_hash_warning) + eh = (struct ppc_link_hash_entry *) eh->elf.root.u.i.link; + + /* Dynamic linking info is on the func descriptor sym. */ + if (eh->oh != NULL + && eh->oh->is_func_descriptor + && (eh->oh->elf.root.type == bfd_link_hash_defined + || eh->oh->elf.root.type == bfd_link_hash_defweak)) + eh = eh->oh; + + if ((eh->elf.root.type == bfd_link_hash_defined + || eh->elf.root.type == bfd_link_hash_defweak) + && (eh->elf.ref_dynamic + || (!info->executable + && eh->elf.def_regular + && ELF_ST_VISIBILITY (eh->elf.other) != STV_INTERNAL + && ELF_ST_VISIBILITY (eh->elf.other) != STV_HIDDEN))) + { + asection *code_sec; + + eh->elf.root.u.def.section->flags |= SEC_KEEP; + + /* Function descriptor syms cause the associated + function code sym section to be marked. */ + if (eh->is_func_descriptor + && (eh->oh->elf.root.type == bfd_link_hash_defined + || eh->oh->elf.root.type == bfd_link_hash_defweak)) + eh->oh->elf.root.u.def.section->flags |= SEC_KEEP; + else if (get_opd_info (eh->elf.root.u.def.section) != NULL + && opd_entry_value (eh->elf.root.u.def.section, + eh->elf.root.u.def.value, + &code_sec, NULL) != (bfd_vma) -1) + code_sec->flags |= SEC_KEEP; + } + + return TRUE; +} + /* Return the section that should be marked against GC for a given relocation. */ diff --git a/bfd/elflink.c b/bfd/elflink.c index a065dca83ea..0336a29137e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1,6 +1,6 @@ /* ELF linking support for BFD. - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. + Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -9067,8 +9067,8 @@ elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp) 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 *inf) +bfd_boolean +bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf) { struct bfd_link_info *info = (struct bfd_link_info *) inf; @@ -9097,8 +9097,9 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) asection * (*gc_mark_hook) (asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *h, Elf_Internal_Sym *); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); - if (!get_elf_backend_data (abfd)->can_gc_sections + if (!bed->can_gc_sections || info->relocatable || info->emitrelocations || !is_elf_hash_table (info->hash)) @@ -9124,11 +9125,11 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) /* Mark dynamically referenced symbols. */ if (elf_hash_table (info)->dynamic_sections_created) elf_link_hash_traverse (elf_hash_table (info), - elf_gc_mark_dynamic_ref_symbol, + bed->gc_mark_dynamic_ref, info); /* Grovel through relocs to find out who stays ... */ - gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook; + gc_mark_hook = bed->gc_mark_hook; for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) { asection *o; diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index d8a15cf46f7..7fa5c7786ae 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -1,6 +1,6 @@ /* Target definitions for NN-bit ELF Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005 Free Software Foundation, Inc. + 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -125,6 +125,9 @@ #ifndef elf_backend_want_got_sym #define elf_backend_want_got_sym 1 #endif +#ifndef elf_backend_gc_mark_dynamic_ref +#define elf_backend_gc_mark_dynamic_ref bfd_elf_gc_mark_dynamic_ref_symbol +#endif #ifndef elf_backend_gc_mark_hook #define elf_backend_gc_mark_hook NULL #endif @@ -587,6 +590,7 @@ static const struct elf_backend_data elfNN_bed = elf_backend_final_write_processing, elf_backend_additional_program_headers, elf_backend_modify_segment_map, + elf_backend_gc_mark_dynamic_ref, elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook, elf_backend_post_process_headers, -- 2.30.2