diff options
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 0ba5759..6819b34 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -496,6 +496,7 @@ struct elf64_x86_64_link_hash_table asection *igotplt; asection *iplt; asection *irelplt; + asection *irelifunc; /* The offset into splt of the PLT entry for the TLS descriptor resolver. Special values are 0, if not necessary (or not found @@ -591,6 +592,7 @@ elf64_x86_64_link_hash_table_create (bfd *abfd) ret->igotplt= NULL; ret->iplt = NULL; ret->irelplt= NULL; + ret->irelifunc = NULL; ret->sym_sec.abfd = NULL; ret->tlsdesc_plt = 0; ret->tlsdesc_got = 0; @@ -1065,21 +1067,30 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_X86_64_PLT32: case R_X86_64_GOTPCREL: case R_X86_64_GOTPCREL64: - if (!info->shared && htab->iplt == NULL) + if (htab->irelifunc == NULL && htab->iplt == NULL) { - if (!_bfd_elf_create_static_ifunc_sections (abfd, - info)) + if (!_bfd_elf_create_ifunc_sections (abfd, info)) return FALSE; - htab->iplt = bfd_get_section_by_name (abfd, ".iplt"); - htab->irelplt = bfd_get_section_by_name (abfd, - ".rela.iplt"); - htab->igotplt = bfd_get_section_by_name (abfd, - ".igot.plt"); - if (!htab->iplt - || !htab->irelplt - || !htab->igotplt) - abort (); + if (info->shared) + { + htab->irelifunc = bfd_get_section_by_name (abfd, + ".rela.ifunc"); + if (!htab->irelifunc) + abort (); + } + else + { + htab->iplt = bfd_get_section_by_name (abfd, ".iplt"); + htab->irelplt = bfd_get_section_by_name (abfd, + ".rela.iplt"); + htab->igotplt = bfd_get_section_by_name (abfd, + ".igot.plt"); + if (!htab->iplt + || !htab->irelplt + || !htab->igotplt) + abort (); + } } break; } @@ -1880,10 +1891,7 @@ elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) /* Finally, allocate space. */ for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection * sreloc = elf_section_data (p->sec)->sreloc; - sreloc->size += p->count * sizeof (Elf64_External_Rela); - } + htab->irelifunc->size += p->count * sizeof (Elf64_External_Rela); /* For STT_GNU_IFUNC symbol, .got.plt has the real function addres and .got has the PLT entry adddress. We will load @@ -2730,7 +2738,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, outrel.r_addend = 0; } - sreloc = elf_section_data (input_section)->sreloc; + sreloc = htab->irelifunc; loc = sreloc->contents; loc += (sreloc->reloc_count++ * sizeof (Elf64_External_Rela)); |