diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2011-10-21 15:13:37 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2011-10-21 15:13:37 +0000 |
commit | e1f987424b7b3f5ac63a2a6ae044a202a44b8ff8 (patch) | |
tree | 3d07b587ea6ee595937027d07e992bb434085d08 /bfd/elf32-i386.c | |
parent | f8e24652cb7bb02eb602d1c8a10ef068b8612cf9 (diff) | |
download | gdb-e1f987424b7b3f5ac63a2a6ae044a202a44b8ff8.zip gdb-e1f987424b7b3f5ac63a2a6ae044a202a44b8ff8.tar.gz gdb-e1f987424b7b3f5ac63a2a6ae044a202a44b8ff8.tar.bz2 |
Put IRELATIVE relocations after JUMP_SLOT.
bfd/
2011-10-21 H.J. Lu <hongjiu.lu@intel.com>
PR ld/13302
* elf32-i386.c (elf_i386_link_hash_table): Add next_jump_slot_index
and next_irelative_index.
(elf_i386_link_hash_table_create): Initialize next_jump_slot_index
and next_irelative_index.
(elf_i386_allocate_dynrelocs): Increment reloc_count instead of
next_tls_desc_index.
(elf_i386_size_dynamic_sections): Set next_tls_desc_index and
next_irelative_index from reloc_count.
(elf_i386_finish_dynamic_symbol): Put R_386_IRELATIVE after
R_386_JUMP_SLOT.
* elf64-x86-64.c (elf_x86_64_link_hash_table): Add
next_jump_slot_index and next_irelative_index.
(elf_x86_64_link_hash_table_create): Initialize
next_jump_slot_index and next_irelative_index.
(elf_x86_64_size_dynamic_sections): Set next_irelative_index
from reloc_count.
(elf_x86_64_finish_dynamic_symbol): Put R_X86_64_IRELATIVE after
R_X86_64_JUMP_SLOT.
ld/testsuite/
2011-10-21 H.J. Lu <hongjiu.lu@intel.com>
PR ld/13302
* ld-ifunc/ifunc-16-i386.d: New.
* ld-ifunc/ifunc-16-x86-64.d: Likewise.
* ld-ifunc/ifunc-16-x86.s: Likewise.
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 7ef1fc1..c3156bd 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -806,6 +806,12 @@ struct elf_i386_link_hash_table /* The index of the next unused R_386_TLS_DESC slot in .rel.plt. */ bfd_vma next_tls_desc_index; + + /* The index of the next unused R_386_JUMP_SLOT slot in .rel.plt. */ + bfd_vma next_jump_slot_index; + + /* The index of the next unused R_386_IRELATIVE slot in .rel.plt. */ + bfd_vma next_irelative_index; }; /* Get the i386 ELF linker hash table from a link_info structure. */ @@ -946,6 +952,8 @@ elf_i386_link_hash_table_create (bfd *abfd) ret->sym_cache.abfd = NULL; ret->srelplt2 = NULL; ret->tls_module_base = NULL; + ret->next_jump_slot_index = 0; + ret->next_irelative_index = 0; ret->loc_hash_table = htab_try_create (1024, elf_i386_local_htab_hash, @@ -2275,7 +2283,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* We also need to make an entry in the .rel.plt section. */ htab->elf.srelplt->size += sizeof (Elf32_External_Rel); - htab->next_tls_desc_index++; + htab->elf.srelplt->reloc_count++; if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks && !info->shared) @@ -2700,9 +2708,19 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) incremented. However, when we reserve space for TLS descriptors, it's not incremented, so in order to compute the space reserved for them, it suffices to multiply the reloc count by the jump - slot size. */ + slot size. + + PR ld/13302: We start next_irelative_index at the end of .rela.plt + so that R_386_IRELATIVE entries come last. */ if (htab->elf.srelplt) - htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4; + { + htab->next_tls_desc_index = htab->elf.srelplt->reloc_count; + htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4; + htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1; + } + else if (htab->elf.irelplt) + htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1; + if (htab->elf.sgotplt) { @@ -4364,13 +4382,13 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, if (plt == htab->elf.splt) { - plt_index = h->plt.offset / plt_entry_size - 1; - got_offset = (plt_index + 3) * 4; + got_offset = h->plt.offset / plt_entry_size - 1; + got_offset = (got_offset + 3) * 4; } else { - plt_index = h->plt.offset / plt_entry_size; - got_offset = plt_index * 4; + got_offset = h->plt.offset / plt_entry_size; + got_offset = got_offset * 4; } /* Fill in the entry in the procedure linkage table. */ @@ -4431,18 +4449,6 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, + abed->plt->plt_got_offset); } - /* Don't fill PLT entry for static executables. */ - if (plt == htab->elf.splt) - { - bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), - plt->contents + h->plt.offset - + abed->plt->plt_reloc_offset); - bfd_put_32 (output_bfd, - (h->plt.offset - + abed->plt->plt_plt_offset + 4), - plt->contents + h->plt.offset - + abed->plt->plt_plt_offset); - } - /* Fill in the entry in the global offset table. */ bfd_put_32 (output_bfd, (plt->output_section->vma @@ -4470,12 +4476,29 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, + h->root.u.def.section->output_offset), gotplt->contents + got_offset); rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); + /* R_386_IRELATIVE comes last. */ + plt_index = htab->next_irelative_index--; } else - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT); + { + rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT); + plt_index = htab->next_jump_slot_index++; + } loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel); bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); + /* Don't fill PLT entry for static executables. */ + if (plt == htab->elf.splt) + { + bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), + plt->contents + h->plt.offset + + abed->plt->plt_reloc_offset); + bfd_put_32 (output_bfd, - (h->plt.offset + + abed->plt->plt_plt_offset + 4), + plt->contents + h->plt.offset + + abed->plt->plt_plt_offset); + } + if (!h->def_regular) { /* Mark the symbol as undefined, rather than as defined in |