X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf-ifunc.c;h=ea08329d2ed8b6128d5a2920a8ceb20274a80226;hb=1ee9e8b3d23a202aac82a524353c4ec3366477c7;hp=3ba96c7961705cb9249dab21353e78631596afb3;hpb=7b5b197e80f04c9b95fe7fafbd9907fc61a1e43d;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c index 3ba96c7961..ea08329d2e 100644 --- a/bfd/elf-ifunc.c +++ b/bfd/elf-ifunc.c @@ -1,5 +1,5 @@ /* ELF STT_GNU_IFUNC support. - Copyright 2009 + Copyright 2009-2013 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -104,51 +104,6 @@ _bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info) return TRUE; } -/* For a STT_GNU_IFUNC symbol, create a dynamic reloc section, SRELOC, - for the input section, SEC, and append this reloc to HEAD. */ - -asection * -_bfd_elf_create_ifunc_dyn_reloc (bfd *abfd, struct bfd_link_info *info, - asection *sec, asection *sreloc, - struct elf_dyn_relocs **head) -{ - struct elf_dyn_relocs *p; - struct elf_link_hash_table *htab = elf_hash_table (info); - - if (sreloc == NULL) - { - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (htab->dynobj == NULL) - htab->dynobj = abfd; - - sreloc = _bfd_elf_make_dynamic_reloc_section (sec, htab->dynobj, - bed->s->log_file_align, - abfd, - bed->rela_plts_and_copies_p); - if (sreloc == NULL) - return NULL; - } - - p = *head; - if (p == NULL || p->sec != sec) - { - bfd_size_type amt = sizeof *p; - - p = ((struct elf_dyn_relocs *) bfd_alloc (htab->dynobj, amt)); - if (p == NULL) - return NULL; - p->next = *head; - *head = p; - p->sec = sec; - p->count = 0; - p->pc_count = 0; - } - p->count += 1; - - return sreloc; -} - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs against a STT_GNU_IFUNC symbol definition. */ @@ -175,7 +130,7 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, || info->export_dynamic) && h->pointer_equality_needed) { - info->callbacks->einfo + info->callbacks->einfo (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer " "equality in `%B' can not be used when making an " "executable; recompile with -fPIE and relink with -pie\n"), @@ -187,23 +142,20 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, htab = elf_hash_table (info); + /* When building shared library, we need to handle the case where it is + marked with regular reference, but not non-GOT reference since the + non-GOT reference bit may not be set here. */ + if (info->shared && !h->non_got_ref && h->ref_regular) + for (p = *head; p != NULL; p = p->next) + if (p->count) + { + h->non_got_ref = 1; + goto keep; + } + /* Support garbage collection against STT_GNU_IFUNC symbols. */ if (h->plt.refcount <= 0 && h->got.refcount <= 0) { - /* When building shared library, we need to handle the case - where it is marked with regular reference, but not non-GOT - reference. It may happen if we didn't see STT_GNU_IFUNC - symbol at the time when checking relocations. */ - if (info->shared - && !h->non_got_ref - && h->ref_regular) - for (p = *head; p != NULL; p = p->next) - if (p->count) - { - h->non_got_ref = 1; - goto keep; - } - h->got = htab->init_got_offset; h->plt = htab->init_plt_offset; *head = NULL; @@ -251,7 +203,7 @@ keep: } /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need - the original value for R_*_IRELATIVE. */ + the original value for R_*_IRELATIVE. */ h->plt.offset = plt->size; /* Make room for this entry in the .plt/.iplt section. */