From ad1e85de417647575643fa3c5f04b7877344ee38 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Sun, 16 Dec 2012 23:01:13 +0000 Subject: [PATCH] Don't check IFUNC relocations in elf_*_check_relocs * elf32-i386.c (elf_i386_check_relocs): Don't check IFUNC relocations here. * elf64-x86-64.c (elf_x86_64_check_relocs): Likewise. --- bfd/ChangeLog | 6 +++++ bfd/elf32-i386.c | 69 ++--------------------------------------------- bfd/elf64-x86-64.c | 78 ++---------------------------------------------------- 3 files changed, 10 insertions(+), 143 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 070acb4..035eba6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,11 @@ 2012-12-16 H.J. Lu + * elf32-i386.c (elf_i386_check_relocs): Don't check IFUNC + relocations here. + * elf64-x86-64.c (elf_x86_64_check_relocs): Likewise. + +2012-12-16 H.J. Lu + PR ld/14968 * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Also check local IFUNC references. diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index a188cec..71e9eaf 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1517,73 +1517,8 @@ elf_i386_check_relocs (bfd *abfd, break; } - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle - it here if it is defined in a non-shared object. */ - if (h->type == STT_GNU_IFUNC - && h->def_regular) - { - /* It is referenced by a non-shared object. */ - h->ref_regular = 1; - h->needs_plt = 1; - - /* STT_GNU_IFUNC symbol must go through PLT. */ - h->plt.refcount += 1; - - /* STT_GNU_IFUNC needs dynamic sections. */ - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - - switch (r_type) - { - default: - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' isn't handled by %s"), abfd, - elf_howto_table[r_type].name, - name, __FUNCTION__); - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_386_32: - h->non_got_ref = 1; - h->pointer_equality_needed = 1; - if (info->shared) - { - /* We must copy these reloc types into the - output file. Create a reloc section in - dynobj and make room for this reloc. */ - sreloc = _bfd_elf_create_ifunc_dyn_reloc - (abfd, info, sec, sreloc, - &((struct elf_i386_link_hash_entry *) h)->dyn_relocs); - if (sreloc == NULL) - return FALSE; - } - break; - - case R_386_PC32: - h->non_got_ref = 1; - break; - - case R_386_PLT32: - break; - - case R_386_GOT32: - case R_386_GOTOFF: - h->got.refcount += 1; - if (htab->elf.sgot == NULL - && !_bfd_elf_create_got_section (htab->elf.dynobj, - info)) - return FALSE; - break; - } - - continue; - } + /* It is referenced by a non-shared object. */ + h->ref_regular = 1; } if (! elf_i386_tls_transition (info, abfd, sec, NULL, diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 283681c..a37f793 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1522,82 +1522,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, break; } - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle - it here if it is defined in a non-shared object. */ - if (h->type == STT_GNU_IFUNC - && h->def_regular) - { - /* It is referenced by a non-shared object. */ - h->ref_regular = 1; - h->needs_plt = 1; - - /* STT_GNU_IFUNC symbol must go through PLT. */ - h->plt.refcount += 1; - - /* STT_GNU_IFUNC needs dynamic sections. */ - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - - switch (r_type) - { - default: - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' isn't handled by %s"), abfd, - x86_64_elf_howto_table[r_type].name, - name, __FUNCTION__); - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_X86_64_32: - if (ABI_64_P (abfd)) - goto not_pointer; - case R_X86_64_64: - h->non_got_ref = 1; - h->pointer_equality_needed = 1; - if (info->shared) - { - /* We must copy these reloc types into the output - file. Create a reloc section in dynobj and - make room for this reloc. */ - sreloc = _bfd_elf_create_ifunc_dyn_reloc - (abfd, info, sec, sreloc, - &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs); - if (sreloc == NULL) - return FALSE; - } - break; - - case R_X86_64_32S: - case R_X86_64_PC32: - case R_X86_64_PC64: -not_pointer: - h->non_got_ref = 1; - if (r_type != R_X86_64_PC32 - && r_type != R_X86_64_PC64) - h->pointer_equality_needed = 1; - break; - - case R_X86_64_PLT32: - break; - - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCREL64: - h->got.refcount += 1; - if (htab->elf.sgot == NULL - && !_bfd_elf_create_got_section (htab->elf.dynobj, - info)) - return FALSE; - break; - } - - continue; - } + /* It is referenced by a non-shared object. */ + h->ref_regular = 1; } if (! elf_x86_64_tls_transition (info, abfd, sec, NULL, -- 2.7.4