aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-i386.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/elf32-i386.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/elf32-i386.c')
-rw-r--r--bfd/elf32-i386.c42
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));