summaryrefslogtreecommitdiff
path: root/bfd/elf-ifunc.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl@lucon.org>2009-06-16 13:41:10 +0000
committerH.J. Lu <hjl@lucon.org>2009-06-16 13:41:10 +0000
commit816b793785b83304bacf7bd7e5f5e417597093e0 (patch)
treeea3b0bfdd87301283687fd7211adfe314f30a24b /bfd/elf-ifunc.c
parent8d84b5e503a473901fe5ac857072e4964e80ee5b (diff)
downloadbinutils-redhat-816b793785b83304bacf7bd7e5f5e417597093e0.tar.gz
2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
* 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".
Diffstat (limited to 'bfd/elf-ifunc.c')
-rw-r--r--bfd/elf-ifunc.c105
1 files changed, 105 insertions, 0 deletions
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;
+}