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

@ -1,3 +1,26 @@
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.
2011-10-20 Nick Clifton <nickc@redhat.com>
PR ld/13049

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

View File

@ -698,6 +698,11 @@ struct elf_x86_64_link_hash_table
/* The offset into sgot of the GOT entry used by the PLT entry
above. */
bfd_vma tlsdesc_got;
/* The index of the next R_X86_64_JUMP_SLOT entry in .rela.plt. */
bfd_vma next_jump_slot_index;
/* The index of the next R_X86_64_IRELATIVE entry in .rela.plt. */
bfd_vma next_irelative_index;
};
/* Get the x86-64 ELF linker hash table from a link_info structure. */
@ -839,6 +844,8 @@ elf_x86_64_link_hash_table_create (bfd *abfd)
ret->tls_ld_got.refcount = 0;
ret->sgotplt_jump_table_size = 0;
ret->tls_module_base = NULL;
ret->next_jump_slot_index = 0;
ret->next_irelative_index = 0;
if (ABI_64_P (abfd))
{
@ -2667,10 +2674,18 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
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_X86_64_IRELATIVE entries come last. */
if (htab->elf.srelplt)
htab->sgotplt_jump_table_size
= elf_x86_64_compute_jump_table_size (htab);
{
htab->sgotplt_jump_table_size
= elf_x86_64_compute_jump_table_size (htab);
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->tlsdesc_plt)
{
@ -4205,13 +4220,13 @@ elf_x86_64_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) * GOT_ENTRY_SIZE;
got_offset = h->plt.offset / PLT_ENTRY_SIZE - 1;
got_offset = (got_offset + 3) * GOT_ENTRY_SIZE;
}
else
{
plt_index = h->plt.offset / PLT_ENTRY_SIZE;
got_offset = plt_index * GOT_ENTRY_SIZE;
got_offset = h->plt.offset / PLT_ENTRY_SIZE;
got_offset = got_offset * GOT_ENTRY_SIZE;
}
/* Fill in the entry in the procedure linkage table. */
@ -4233,17 +4248,6 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
- 6),
plt->contents + h->plt.offset + 2);
/* Don't fill PLT entry for static executables. */
if (plt == htab->elf.splt)
{
/* Put relocation index. */
bfd_put_32 (output_bfd, plt_index,
plt->contents + h->plt.offset + 7);
/* Put offset for jmp .PLT0. */
bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
plt->contents + h->plt.offset + 12);
}
/* Fill in the entry in the global offset table, initially this
points to the pushq instruction in the PLT which is at offset 6. */
bfd_put_64 (output_bfd, (plt->output_section->vma
@ -4267,11 +4271,25 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
rela.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
/* R_X86_64_IRELATIVE comes last. */
plt_index = htab->next_irelative_index--;
}
else
{
rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT);
rela.r_addend = 0;
plt_index = htab->next_jump_slot_index++;
}
/* Don't fill PLT entry for static executables. */
if (plt == htab->elf.splt)
{
/* Put relocation index. */
bfd_put_32 (output_bfd, plt_index,
plt->contents + h->plt.offset + 7);
/* Put offset for jmp .PLT0. */
bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
plt->contents + h->plt.offset + 12);
}
bed = get_elf_backend_data (output_bfd);

View File

@ -1,3 +1,10 @@
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.
2011-10-20 Alan Modra <amodra@gmail.com>
* ld-selective/selective.exp: Use check_gc_sections_available.

View File

@ -0,0 +1,10 @@
#source: ifunc-16-x86.s
#ld: -shared -m elf_i386
#as: --32
#readelf: -r --wide
#target: x86_64-*-* i?86-*-*
Relocation section '.rel.plt' at .*
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_JUMP_SLOT[ ]+0+[ ]+ifunc
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]*

View File

@ -0,0 +1,10 @@
#source: ifunc-16-x86.s
#as: --64
#ld: -shared -melf_x86_64
#readelf: -r --wide
#target: x86_64-*-*
Relocation section '.rela.plt' at .*
[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_JUMP_SLOT[ ]+0+[ ]+ifunc \+ 0
[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]*

View File

@ -0,0 +1,17 @@
.text
.globl fct
.type fct, @gnu_indirect_function
.set fct,resolve
.hidden int_fct
.globl int_fct
.set int_fct,fct
.p2align 4,,15
.type resolve, @function
resolve:
call ifunc@PLT
.size resolve, .-resolve
.globl g
.type g, @function
g:
jmp int_fct@PLT
.size g, .-g