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.
This commit is contained in:
parent
f8e24652cb
commit
e1f987424b
7 changed files with 146 additions and 38 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue