From 816b793785b83304bacf7bd7e5f5e417597093e0 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 16 Jun 2009 13:41:10 +0000 Subject: 2009-06-16 H.J. Lu * configure.in (elf): Add elf-ifunc.lo. * configure: Regenerated. * Makefile.in: Likewise. * elf-bfd.h (elf_link_hash_table): Add sgot, sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and irelifunc. * elf32-i386.c (elf_i386_link_hash_table): Remove sgot, sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and irelifunc. (elf_i386_link_hash_table_create): Likewise. (elf_i386_create_dynamic_sections): Likewise. (elf_i386_check_relocs): Likewise. (elf_i386_allocate_dynrelocs): Likewise. (elf_i386_size_dynamic_sections): Likewise. (elf_i386_relocate_section): Likewise. (elf_i386_finish_dynamic_symbol): Likewise. (elf_i386_finish_dynamic_sections): Likewise. (elf_i386_create_got_section): Removed. * elf64-x86-64.c (elf64_x86_64_link_hash_table): Remove sgot, sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and irelifunc. (elf64_x86_64_compute_jump_table_size): Updated. (elf64_x86_64_link_hash_table_create): Likewise. (elf64_x86_64_create_dynamic_sections): Likewise. (elf64_x86_64_check_relocs): Likewise. (elf64_x86_64_allocate_dynrelocs): Likewise. (elf64_x86_64_size_dynamic_sections): Likewise. (elf64_x86_64_relocate_section): Likewise. (elf64_x86_64_finish_dynamic_symbol): Likewise. (elf64_x86_64_finish_dynamic_sections): Likewise. (elf64_x86_64_create_got_section): Removed. * elflink.c (_bfd_elf_create_got_section): Use log_file_align for pointer alignment. Set up section pointers. (_bfd_elf_create_dynamic_sections): Likewise. (_bfd_elf_create_ifunc_sections): Moved to ... * elf-ifunc.c: Here. New. * Makefile.am (BFD32_BACKENDS): Add elf-ifunc.lo. (BFD32_BACKENDS_CFILES): Add elf-ifunc.c. Run "make dep-am". --- bfd/elf-ifunc.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 bfd/elf-ifunc.c (limited to 'bfd/elf-ifunc.c') diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c new file mode 100644 index 0000000000..4bfc31b55c --- /dev/null +++ b/bfd/elf-ifunc.c @@ -0,0 +1,105 @@ +/* ELF STT_GNU_IFUNC support. + Copyright 2009 + Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "bfdlink.h" +#include "libbfd.h" +#define ARCH_SIZE 0 +#include "elf-bfd.h" +#include "safe-ctype.h" +#include "libiberty.h" +#include "objalloc.h" + +/* Create sections needed by STT_GNU_IFUNC symbol. */ + +bfd_boolean +_bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info) +{ + flagword flags, pltflags; + asection *s; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + struct elf_link_hash_table *htab = elf_hash_table (info); + + if (htab->irelifunc != NULL || htab->iplt != NULL) + return TRUE; + + flags = bed->dynamic_sec_flags; + pltflags = flags; + if (bed->plt_not_loaded) + /* We do not clear SEC_ALLOC here because we still want the OS to + allocate space for the section; it's just that there's nothing + to read in from the object file. */ + pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS); + else + pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD; + if (bed->plt_readonly) + pltflags |= SEC_READONLY; + + if (info->shared) + { + /* We need to create .rel[a].ifunc for shared objects. */ + const char *rel_sec = (bed->rela_plts_and_copies_p + ? ".rela.ifunc" : ".rel.ifunc"); + + s = bfd_make_section_with_flags (abfd, rel_sec, + flags | SEC_READONLY); + if (s == NULL + || ! bfd_set_section_alignment (abfd, s, + bed->s->log_file_align)) + return FALSE; + htab->irelifunc = s; + } + else + { + /* We need to create .iplt, .rel[a].iplt, .igot and .igot.plt + for static executables. */ + s = bfd_make_section_with_flags (abfd, ".iplt", pltflags); + if (s == NULL + || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) + return FALSE; + htab->iplt = s; + + s = bfd_make_section_with_flags (abfd, + (bed->rela_plts_and_copies_p + ? ".rela.iplt" : ".rel.iplt"), + flags | SEC_READONLY); + if (s == NULL + || ! bfd_set_section_alignment (abfd, s, + bed->s->log_file_align)) + return FALSE; + htab->irelplt = s; + + /* We don't need the .igot section if we have the .igot.plt + section. */ + if (bed->want_got_plt) + s = bfd_make_section_with_flags (abfd, ".igot.plt", flags); + else + s = bfd_make_section_with_flags (abfd, ".igot", flags); + if (s == NULL + || !bfd_set_section_alignment (abfd, s, + bed->s->log_file_align)) + return FALSE; + htab->igotplt = s; + } + + return TRUE; +} -- cgit v1.2.1