diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 14 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 5 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 106 | ||||
-rw-r--r-- | bfd/elf64-ppc.h | 4 | ||||
-rw-r--r-- | bfd/elflink.c | 21 |
5 files changed, 95 insertions, 55 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bd2d32e..13018bb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,19 @@ 2004-08-09 Alan Modra <amodra@bigpond.net.au> + * elf-bfd.h (_bfd_elf_gc_mark): Declare. + * elflink.c (elf_link_input_bfd): Formatting. + (_bfd_elf_gc_mark): Rename from elf_gc_mark and make global. Adjust + all callers. + * elf64-ppc.c (struct ppc_link_hash_entry): Remove is_entry. + (link_hash_newfunc): Don't set it. + (ppc64_elf_copy_indirect_symbol): Nor copy it. + (ppc64_elf_mark_entry_syms): Delete. + (ppc64_elf_gc_mark_hook): Mark entry syms here. Also mark opd + sections. Use get_opd_info. + * elf64-ppc.h (ppc64_elf_mark_entry_syms): Delete. + +2004-08-09 Alan Modra <amodra@bigpond.net.au> + * elf64-ppc.c (adjust_opd_syms): Fix merge error. * elf64-ppc.c (struct ppc_link_hash_table): Remove have_undefweak. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index e1a0075..d2bce6d 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1710,6 +1710,11 @@ extern bfd_boolean bfd_elf_gc_record_vtinherit extern bfd_boolean bfd_elf_gc_record_vtentry (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); +extern bfd_boolean _bfd_elf_gc_mark + (struct bfd_link_info *, asection *, + asection * (*) (asection *, struct bfd_link_info *, Elf_Internal_Rela *, + struct elf_link_hash_entry *, Elf_Internal_Sym *)); + extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets (bfd *, struct bfd_link_info *); diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index b8fbb71..64a7246 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -2776,7 +2776,6 @@ struct ppc_link_hash_entry /* Flag function code and descriptor symbols. */ unsigned int is_func:1; unsigned int is_func_descriptor:1; - unsigned int is_entry:1; /* Whether global opd sym has been adjusted or not. */ unsigned int adjust_done:1; @@ -2986,7 +2985,6 @@ link_hash_newfunc (struct bfd_hash_entry *entry, eh->oh = NULL; eh->is_func = 0; eh->is_func_descriptor = 0; - eh->is_entry = 0; eh->adjust_done = 0; eh->tls_mask = 0; } @@ -3372,7 +3370,6 @@ ppc64_elf_copy_indirect_symbol edir->is_func |= eind->is_func; edir->is_func_descriptor |= eind->is_func_descriptor; - edir->is_entry |= eind->is_entry; edir->tls_mask |= eind->tls_mask; mask = (ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR @@ -3464,27 +3461,6 @@ ppc64_elf_copy_indirect_symbol BFD_ASSERT (eind->elf.dynindx == -1); } -/* Set a flag, used by ppc64_elf_gc_mark_hook, on the entry symbol and - symbols undefined on the command-line. */ - -bfd_boolean -ppc64_elf_mark_entry_syms (struct bfd_link_info *info) -{ - struct ppc_link_hash_table *htab; - struct bfd_sym_chain *sym; - - htab = ppc_hash_table (info); - for (sym = info->gc_sym_list; sym; sym = sym->next) - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE); - if (h != NULL) - ((struct ppc_link_hash_entry *) h)->is_entry = 1; - } - return TRUE; -} - /* Hack symbols defined in .opd sections to be function type. */ static bfd_boolean @@ -4121,17 +4097,59 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, static asection * ppc64_elf_gc_mark_hook (asection *sec, - struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct bfd_link_info *info, Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, Elf_Internal_Sym *sym) { - asection *rsec = NULL; + asection *rsec; + + /* First mark all our entry sym sections. */ + if (info->gc_sym_list != NULL) + { + struct ppc_link_hash_table *htab = ppc_hash_table (info); + struct bfd_sym_chain *sym = info->gc_sym_list; + + info->gc_sym_list = NULL; + do + { + struct ppc_link_hash_entry *eh; + + eh = (struct ppc_link_hash_entry *) + elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE); + if (eh == NULL) + continue; + if (eh->elf.root.type != bfd_link_hash_defined + && eh->elf.root.type != bfd_link_hash_defweak) + continue; + + if (eh->is_func_descriptor) + rsec = eh->oh->elf.root.u.def.section; + else + continue; + + if (!rsec->gc_mark) + _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook); + + rsec = eh->elf.root.u.def.section; + if (!rsec->gc_mark) + _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook); + + sym = sym->next; + } + while (sym != NULL); + } + + /* Syms return NULL if we're marking .opd, so we avoid marking all + function sections, as all functions are referenced in .opd. */ + rsec = NULL; + if (get_opd_info (sec) != NULL) + return rsec; if (h != NULL) { enum elf_ppc64_reloc_type r_type; - struct ppc_link_hash_entry *fdh; + struct ppc_link_hash_entry *eh; r_type = ELF64_R_TYPE (rel->r_info); switch (r_type) @@ -4145,19 +4163,22 @@ ppc64_elf_gc_mark_hook (asection *sec, { case bfd_link_hash_defined: case bfd_link_hash_defweak: - fdh = (struct ppc_link_hash_entry *) h; + eh = (struct ppc_link_hash_entry *) h; + if (eh->oh != NULL && eh->oh->is_func_descriptor) + eh = eh->oh; /* Function descriptor syms cause the associated function code sym section to be marked. */ - if (fdh->is_func_descriptor) - rsec = fdh->oh->elf.root.u.def.section; - - /* Function entry syms return NULL if they are in .opd - and are not ._start (or others undefined on the ld - command line). Thus we avoid marking all function - sections, as all functions are referenced in .opd. */ - else if ((fdh->oh != NULL && fdh->oh->is_entry) - || ppc64_elf_section_data (sec)->opd.func_sec == NULL) + if (eh->is_func_descriptor) + { + /* They also mark their opd section. */ + if (!eh->elf.root.u.def.section->gc_mark) + _bfd_elf_gc_mark (info, eh->elf.root.u.def.section, + ppc64_elf_gc_mark_hook); + + rsec = eh->oh->elf.root.u.def.section; + } + else rsec = h->root.u.def.section; break; @@ -4175,11 +4196,14 @@ ppc64_elf_gc_mark_hook (asection *sec, asection **opd_sym_section; rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx); - opd_sym_section = ppc64_elf_section_data (rsec)->opd.func_sec; + opd_sym_section = get_opd_info (rsec); if (opd_sym_section != NULL) - rsec = opd_sym_section[sym->st_value / 24]; - else if (ppc64_elf_section_data (sec)->opd.func_sec != NULL) - rsec = NULL; + { + if (!rsec->gc_mark) + _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook); + + rsec = opd_sym_section[sym->st_value / 24]; + } } return rsec; diff --git a/bfd/elf64-ppc.h b/bfd/elf64-ppc.h index 998e7e1..171e552 100644 --- a/bfd/elf64-ppc.h +++ b/bfd/elf64-ppc.h @@ -1,5 +1,5 @@ /* PowerPC64-specific support for 64-bit ELF. - Copyright 2002, 2003 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -19,8 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ void ppc64_elf_init_stub_bfd (bfd *, struct bfd_link_info *); -bfd_boolean ppc64_elf_mark_entry_syms - (struct bfd_link_info *); bfd_boolean ppc64_elf_edit_opd (bfd *, struct bfd_link_info *); asection *ppc64_elf_tls_setup diff --git a/bfd/elflink.c b/bfd/elflink.c index 5eb0c93..7c7414a 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -6710,10 +6710,9 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) } else if (complain) { - char *r_sec - = bfd_get_section_ident (o); - char *d_sec - = bfd_get_section_ident (sec); + char *r_sec = bfd_get_section_ident (o); + char *d_sec = bfd_get_section_ident (sec); + finfo->info->callbacks->error_handler (LD_DEFINITION_IN_DISCARDED_SECTION, _("`%T' referenced in section `%s' of %B: " @@ -8366,10 +8365,10 @@ typedef asection * (*gc_mark_hook_fn) (asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *); -static bfd_boolean -elf_gc_mark (struct bfd_link_info *info, - asection *sec, - gc_mark_hook_fn gc_mark_hook) +bfd_boolean +_bfd_elf_gc_mark (struct bfd_link_info *info, + asection *sec, + gc_mark_hook_fn gc_mark_hook) { bfd_boolean ret; asection *group_sec; @@ -8379,7 +8378,7 @@ elf_gc_mark (struct bfd_link_info *info, /* Mark all the sections in the group. */ group_sec = elf_section_data (sec)->next_in_group; if (group_sec && !group_sec->gc_mark) - if (!elf_gc_mark (info, group_sec, gc_mark_hook)) + if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook)) return FALSE; /* Look through the section relocs. */ @@ -8460,7 +8459,7 @@ elf_gc_mark (struct bfd_link_info *info, { if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour) rsec->gc_mark = 1; - else if (!elf_gc_mark (info, rsec, gc_mark_hook)) + else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook)) { ret = FALSE; goto out2; @@ -8767,7 +8766,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) EH frame section. */ if (strcmp (o->name, ".eh_frame") == 0) o->gc_mark = 1; - else if (!elf_gc_mark (info, o, gc_mark_hook)) + else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) return FALSE; } } |