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:
H.J. Lu 2011-10-21 15:13:37 +00:00
parent f8e24652cb
commit e1f987424b
7 changed files with 146 additions and 38 deletions

View file

@ -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