diff options
Diffstat (limited to 'binutils/patches/167_pr13302.diff')
-rw-r--r-- | binutils/patches/167_pr13302.diff | 532 |
1 files changed, 532 insertions, 0 deletions
diff --git a/binutils/patches/167_pr13302.diff b/binutils/patches/167_pr13302.diff new file mode 100644 index 0000000..13723eb --- /dev/null +++ b/binutils/patches/167_pr13302.diff @@ -0,0 +1,532 @@ +# DP: Fix PR ld/13302, taken from the trunk + +bfd/ + +2012-03-06 Jakub Jelinek <jakub@redhat.com> + + * elf64-x86-64.c (elf_x86_64_relocate_section): For R_X86_64_RELATIVE + set relocate to TRUE. + +2011-10-21 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/13302 + * elf32-i386.c (elf_i386_relocate_section): Replace + R_386_IRELATIVE with R_386_RELATIVE. + + * elf64-x86-64.c (elf_x86_64_relocate_section): Replace + R_X86_64_IRELATIVE with R_X86_64_RELATIVE. + +2011-10-21 H.J. Lu <hongjiu.lu@intel.com>. + + * elf32-i386.c (elf_i386_relocate_section): Fix a typo in + comments. + * elf64-x86-64.c (elf_x86_64_relocate_section): Likewise. + +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-i386/i386.exp: Run pr13302. + + * ld-i386/pr13302.d: New. + * ld-i386/pr13302.s: Likewise. + + * ld-x86-64/pr13082-5b.d: Updated. + * ld-x86-64/pr13082-6a.d: Likewise. + * ld-x86-64/pr13082-6b.d: Likewise. + +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. + +diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c +index 7ef1fc1..d187305 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) + { +@@ -3232,13 +3250,14 @@ elf_i386_relocate_section (bfd *output_bfd, + + case R_386_32: + /* Generate dynamic relcoation only when there is a +- non-GOF reference in a shared object. */ ++ non-GOT reference in a shared object. */ + if (info->shared && h->non_got_ref) + { + Elf_Internal_Rela outrel; + bfd_byte *loc; + asection *sreloc; + bfd_vma offset; ++ bfd_boolean relocate; + + /* Need a dynamic relocation to get the real function + adddress. */ +@@ -3259,15 +3278,14 @@ elf_i386_relocate_section (bfd *output_bfd, + || info->executable) + { + /* This symbol is resolved locally. */ +- outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); +- bfd_put_32 (output_bfd, +- (h->root.u.def.value +- + h->root.u.def.section->output_section->vma +- + h->root.u.def.section->output_offset), +- contents + offset); ++ outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); ++ relocate = TRUE; + } + else +- outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); ++ { ++ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); ++ relocate = FALSE; ++ } + + sreloc = htab->elf.irelifunc; + loc = sreloc->contents; +@@ -3280,7 +3298,8 @@ elf_i386_relocate_section (bfd *output_bfd, + we need to include the symbol value so that it + becomes an addend for the dynamic reloc. For an + internal symbol, we have updated addend. */ +- continue; ++ if (! relocate) ++ continue; + } + /* FALLTHROUGH */ + case R_386_PC32: +@@ -4364,13 +4383,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 +4450,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 +4477,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 +diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c +index e4c3946..2206dd4 100644 +--- a/bfd/elf64-x86-64.c ++++ b/bfd/elf64-x86-64.c +@@ -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) + { +@@ -3141,11 +3156,12 @@ elf_x86_64_relocate_section (bfd *output_bfd, + } + + /* Generate dynamic relcoation only when there is a +- non-GOF reference in a shared object. */ ++ non-GOT reference in a shared object. */ + if (info->shared && h->non_got_ref) + { + Elf_Internal_Rela outrel; + asection *sreloc; ++ bfd_boolean relocate; + + /* Need a dynamic relocation to get the real function + address. */ +@@ -3165,15 +3181,15 @@ elf_x86_64_relocate_section (bfd *output_bfd, + || info->executable) + { + /* This symbol is resolved locally. */ +- outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE); +- outrel.r_addend = (h->root.u.def.value +- + h->root.u.def.section->output_section->vma +- + h->root.u.def.section->output_offset); ++ outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); ++ outrel.r_addend = relocation; ++ relocate = TRUE; + } + else + { + outrel.r_info = htab->r_info (h->dynindx, r_type); + outrel.r_addend = 0; ++ relocate = FALSE; + } + + sreloc = htab->elf.irelifunc; +@@ -3184,7 +3200,8 @@ elf_x86_64_relocate_section (bfd *output_bfd, + we need to include the symbol value so that it + becomes an addend for the dynamic reloc. For an + internal symbol, we have updated addend. */ +- continue; ++ if (! relocate) ++ continue; + } + /* FALLTHROUGH */ + case R_X86_64_PC32: +@@ -4205,13 +4222,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 +4250,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 +4273,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); +diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp +index 68b71fb..1727922 100644 +--- a/ld/testsuite/ld-i386/i386.exp ++++ b/ld/testsuite/ld-i386/i386.exp +@@ -210,3 +210,4 @@ if { !([istarget "i?86-*-linux*"] + + run_dump_test "compressed1" + run_dump_test "pr12627" ++run_dump_test "pr13302" +diff --git a/ld/testsuite/ld-i386/pr13302.d b/ld/testsuite/ld-i386/pr13302.d +new file mode 100644 +index 0000000..3d85d08 +--- /dev/null ++++ b/ld/testsuite/ld-i386/pr13302.d +@@ -0,0 +1,12 @@ ++#name: PR ld/13302 ++#as: --32 ++#ld: -pie -melf_i386 ++#readelf: -r --wide ++ ++Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 1 entries: ++ Offset Info Type Sym. Value Symbol's Name ++[0-9a-f]+ +[0-9a-f]+ +R_386_RELATIVE + ++ ++Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries: ++ Offset Info Type Sym. Value Symbol's Name ++[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE + +diff --git a/ld/testsuite/ld-i386/pr13302.s b/ld/testsuite/ld-i386/pr13302.s +new file mode 100644 +index 0000000..cfd2717 +--- /dev/null ++++ b/ld/testsuite/ld-i386/pr13302.s +@@ -0,0 +1,11 @@ ++ .text ++ .globl _start ++ .type ifunc, @gnu_indirect_function ++_start: ++ lea .Ljmp@GOTOFF(%ebx), %eax ++ifunc: ++ jmp *(%eax) ++ .section .data.rel.ro.local,"aw",@progbits ++ .align 4 ++.Ljmp: ++ .long ifunc +diff --git a/ld/testsuite/ld-ifunc/ifunc-16-i386.d b/ld/testsuite/ld-ifunc/ifunc-16-i386.d +new file mode 100644 +index 0000000..8ae3d0a +--- /dev/null ++++ b/ld/testsuite/ld-ifunc/ifunc-16-i386.d +@@ -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[ ]* +diff --git a/ld/testsuite/ld-ifunc/ifunc-16-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-16-x86-64.d +new file mode 100644 +index 0000000..d69626d +--- /dev/null ++++ b/ld/testsuite/ld-ifunc/ifunc-16-x86-64.d +@@ -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]* +diff --git a/ld/testsuite/ld-ifunc/ifunc-16-x86.s b/ld/testsuite/ld-ifunc/ifunc-16-x86.s +new file mode 100644 +index 0000000..fb38253 +--- /dev/null ++++ b/ld/testsuite/ld-ifunc/ifunc-16-x86.s +@@ -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 +diff --git a/ld/testsuite/ld-x86-64/pr13082-5b.d b/ld/testsuite/ld-x86-64/pr13082-5b.d +index 1c5a5e7..48e37c3 100644 +--- a/ld/testsuite/ld-x86-64/pr13082-5b.d ++++ b/ld/testsuite/ld-x86-64/pr13082-5b.d +@@ -6,7 +6,7 @@ + + Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: + Offset Info Type Sym. Value Symbol's Name \+ Addend +-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ ++[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+ + + Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: + Offset Info Type Sym. Value Symbol's Name \+ Addend +diff --git a/ld/testsuite/ld-x86-64/pr13082-6a.d b/ld/testsuite/ld-x86-64/pr13082-6a.d +index 9a1a655..de90bb8 100644 +--- a/ld/testsuite/ld-x86-64/pr13082-6a.d ++++ b/ld/testsuite/ld-x86-64/pr13082-6a.d +@@ -6,7 +6,7 @@ + + Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: + Offset Info Type Sym. Value Symbol's Name \+ Addend +-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ ++[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+ + + Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: + Offset Info Type Sym. Value Symbol's Name \+ Addend +diff --git a/ld/testsuite/ld-x86-64/pr13082-6b.d b/ld/testsuite/ld-x86-64/pr13082-6b.d +index 792c348..66ff59b 100644 +--- a/ld/testsuite/ld-x86-64/pr13082-6b.d ++++ b/ld/testsuite/ld-x86-64/pr13082-6b.d +@@ -6,7 +6,7 @@ + + Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries: + Offset Info Type Sym. Value Symbol's Name \+ Addend +-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+ ++[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+ + + Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries: + Offset Info Type Sym. Value Symbol's Name \+ Addend |