summaryrefslogtreecommitdiffstats
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2009-06-06 22:39:25 +0000
committerH.J. Lu <hjl.tools@gmail.com>2009-06-06 22:39:25 +0000
commit2a81c24ab145893771d1d64f204af5f864b67f2e (patch)
tree6ad54f8da71960f9ffb53e31e300d04bcac06e88 /bfd/elflink.c
parent0e7c7f11f471e3350d50c08fda8e3ddf055940f2 (diff)
downloadppe42-binutils-2a81c24ab145893771d1d64f204af5f864b67f2e.tar.gz
ppe42-binutils-2a81c24ab145893771d1d64f204af5f864b67f2e.zip
bfd/
2009-06-06 H.J. Lu <hongjiu.lu@intel.com> * elf32-i386.c (elf_i386_link_hash_table): Add irelifunc. (elf_i386_link_hash_table_create): Initialize irelifunc. (elf_i386_check_relocs): Updated. Set up irelifunc for shared objects. (elf_i386_allocate_dynrelocs): Use irelifunc for dynamic relocation for non-GOT reference of STT_GNU_IFUNC symbol in shared objects. (elf_i386_relocate_section): Likewise. * elf64-x86-64.c (elf64_x86_64_link_hash_table): Add irelifunc. (elf64_x86_64_link_hash_table_create): Initialize irelifunc. (elf64_x86_64_check_relocs): Updated. Set up irelifunc for shared objects. (elf64_x86_64_allocate_dynrelocs): Use irelifunc for dynamic relocation for non-GOT reference of STT_GNU_IFUNC symbol in shared objects. (elf64_x86_64_relocate_section): Likewise. * elf-bfd.h (_bfd_elf_create_static_ifunc_sections): Renamed to ... (_bfd_elf_create_ifunc_sections): This. * elflink.c (_bfd_elf_create_static_ifunc_sections): Renamd to ... (_bfd_elf_create_ifunc_sections): This. Create .rel[a].ifunc for shared objects. ld/ 2009-06-06 H.J. Lu <hongjiu.lu@intel.com> * scripttempl/elf.sc: Add .rel.ifunc and .rela.ifunc.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c107
1 files changed, 57 insertions, 50 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index d18280764a..e3a1670704 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12492,31 +12492,17 @@ _bfd_elf_make_dynamic_reloc_section (asection * sec,
return reloc_sec;
}
-/* Create sections needed by STT_GNU_IFUNC symbol for static
- executables. */
+/* Create sections needed by STT_GNU_IFUNC symbol. */
bfd_boolean
-_bfd_elf_create_static_ifunc_sections (bfd *abfd,
- struct bfd_link_info *info)
+_bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
{
flagword flags, pltflags;
int ptralign;
asection *s;
- const struct elf_backend_data *bed;
-
- /* Should never be called for shared library. */
- BFD_ASSERT (!info->shared);
-
- /* This function may be called more than once. */
- s = bfd_get_section_by_name (abfd, ".iplt");
- if (s != NULL)
- return TRUE;
-
- bed = get_elf_backend_data (abfd);
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
- /* We need to create .iplt, .rel[a].iplt, .igot, .igot.plt, */
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
@@ -12528,47 +12514,68 @@ _bfd_elf_create_static_ifunc_sections (bfd *abfd,
if (bed->plt_readonly)
pltflags |= SEC_READONLY;
- s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
- if (s == NULL
- || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
- return FALSE;
-
- 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;
-
- switch (bed->s->arch_size)
+ if (info->shared)
{
- case 32:
- ptralign = 2;
- break;
+ /* We need to create .rel[a].ifunc for shared objects. */
+ const char *rel_sec = (bed->rela_plts_and_copies_p
+ ? ".rela.ifunc" : ".rel.ifunc");
- case 64:
- ptralign = 3;
- break;
-
- default:
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
-
- /* We don't need the .igot section if we have the .igot.plt
- section. */
+ /* This function should be called only once. */
+ s = bfd_get_section_by_name (abfd, rel_sec);
+ if (s != NULL)
+ abort ();
- if (bed->want_got_plt)
- {
- s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
+ s = bfd_make_section_with_flags (abfd, rel_sec,
+ flags | SEC_READONLY);
if (s == NULL
- || !bfd_set_section_alignment (abfd, s, ptralign))
+ || ! bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
return FALSE;
}
else
{
- s = bfd_make_section_with_flags (abfd, ".igot", flags);
+ /* This function should be called only once. */
+ s = bfd_get_section_by_name (abfd, ".iplt");
+ if (s != NULL)
+ abort ();
+
+ /* 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;
+
+ 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;
+
+ switch (bed->s->arch_size)
+ {
+ case 32:
+ ptralign = 2;
+ break;
+
+ case 64:
+ ptralign = 3;
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* 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, ptralign))
return FALSE;
OpenPOWER on IntegriCloud