diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2009-06-06 22:39:25 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2009-06-06 22:39:25 +0000 |
commit | 2a81c24ab145893771d1d64f204af5f864b67f2e (patch) | |
tree | 6ad54f8da71960f9ffb53e31e300d04bcac06e88 /bfd/elf32-i386.c | |
parent | 0e7c7f11f471e3350d50c08fda8e3ddf055940f2 (diff) | |
download | gdb-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/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 8fb8742..b2918cf 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -678,6 +678,7 @@ struct elf_i386_link_hash_table asection *igotplt; asection *iplt; asection *irelplt; + asection *irelifunc; /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. */ asection *srelplt2; @@ -777,6 +778,7 @@ elf_i386_link_hash_table_create (bfd *abfd) ret->igotplt= NULL; ret->iplt = NULL; ret->irelplt= NULL; + ret->irelifunc = NULL; ret->tls_ldm_got.refcount = 0; ret->next_tls_desc_index = 0; ret->sgotplt_jump_table_size = 0; @@ -1279,21 +1281,30 @@ elf_i386_check_relocs (bfd *abfd, case R_386_PLT32: case R_386_GOT32: case R_386_GOTOFF: - 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, - ".rel.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, + ".rel.ifunc"); + if (!htab->irelifunc) + abort (); + } + else + { + htab->iplt = bfd_get_section_by_name (abfd, ".iplt"); + htab->irelplt = bfd_get_section_by_name (abfd, + ".rel.iplt"); + htab->igotplt = bfd_get_section_by_name (abfd, + ".igot.plt"); + if (!htab->iplt + || !htab->irelplt + || !htab->igotplt) + abort (); + } } break; } @@ -2038,10 +2049,7 @@ elf_i386_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 (Elf32_External_Rel); - } + htab->irelifunc->size += p->count * sizeof (Elf32_External_Rel); /* For STT_GNU_IFUNC symbol, .got.plt has the real function addres and .got has the PLT entry adddress. We will load @@ -3010,7 +3018,7 @@ elf_i386_relocate_section (bfd *output_bfd, else outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - sreloc = elf_section_data (input_section)->sreloc; + sreloc = htab->irelifunc; loc = sreloc->contents; loc += (sreloc->reloc_count++ * sizeof (Elf32_External_Rel)); |