aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.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/elf64-x86-64.c
parent0e7c7f11f471e3350d50c08fda8e3ddf055940f2 (diff)
downloadgdb-2a81c24ab145893771d1d64f204af5f864b67f2e.zip
gdb-2a81c24ab145893771d1d64f204af5f864b67f2e.tar.gz
gdb-2a81c24ab145893771d1d64f204af5f864b67f2e.tar.bz2
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/elf64-x86-64.c')
-rw-r--r--bfd/elf64-x86-64.c42
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));