mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-30 13:33:53 +08:00
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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
10
ld/testsuite/ld-ifunc/ifunc-16-i386.d
Normal file
10
ld/testsuite/ld-ifunc/ifunc-16-i386.d
Normal 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[ ]*
|
10
ld/testsuite/ld-ifunc/ifunc-16-x86-64.d
Normal file
10
ld/testsuite/ld-ifunc/ifunc-16-x86-64.d
Normal 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]*
|
17
ld/testsuite/ld-ifunc/ifunc-16-x86.s
Normal file
17
ld/testsuite/ld-ifunc/ifunc-16-x86.s
Normal 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
|
Loading…
Reference in New Issue
Block a user