diff --git a/.cvsignore b/.cvsignore index 3ef1fb0..9020bea 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1,3 @@ binutils-2.19.51.0.14.tar.bz2 +i386 +binutils-2.19.51.0.14 diff --git a/binutils-2.19.51.0.14-ppc-hidden-plt-relocs.patch b/binutils-2.19.51.0.14-ppc-hidden-plt-relocs.patch new file mode 100644 index 0000000..e1f0f46 --- /dev/null +++ b/binutils-2.19.51.0.14-ppc-hidden-plt-relocs.patch @@ -0,0 +1,315 @@ +diff -rup ../binutils-2.19.51.0.14.original/bfd/ChangeLog bfd/ChangeLog +--- ../binutils-2.19.51.0.14.original/bfd/ChangeLog 2010-02-08 15:39:17.000000000 +0000 ++++ bfd/ChangeLog 2010-02-08 15:40:38.000000000 +0000 +@@ -1,3 +1,30 @@ ++2010-02-08 Nick Clifton ++ ++ BZ 562249 ++ Import this patch from the mainline: ++ ++ 2009-12-17 Alan Modra ++ ++ PR ld/11088 ++ * elf64-ppc.c (ppc64_elf_gc_sweep_hook): Don't abort if symbol ++ hiding has nulled out plt.plist. ++ ++ PR ld/11088 ++ * elf32-ppc.c (update_plt_info): Clear sec here when addend is ++ less than 32768.. ++ (ppc_elf_check_relocs): ..rather than doing so here. Ignore new ++ relax relocs. ++ (ppc_elf_gc_sweep_hook): Don't segfault when symbol hiding has ++ removed plt_entry records. ++ (ppc_elf_tls_setup): Handle PIE calls to __tls_get_addr correctly. ++ (ppc_elf_tls_optimize): Likewise. Also dec __tls_get_addr refcount ++ when optimizing code using new tlsgd and tlsld marker relocs. ++ (ppc_elf_relax_section): Differentiate relaxed PLTREL24 relocs ++ from ADDR24 relocs using plt or glink. Don't clear the addend ++ for R_PPC_RELAX_PLTREL24. ++ (ppc_elf_relocate_section): Correctly handle addends on relaxed ++ PLTREL24 relocs. ++ + 2009-07-22 H.J. Lu + + PR ld/10433 +diff -rup ../binutils-2.19.51.0.14.original/bfd/elf32-ppc.c bfd/elf32-ppc.c +--- ../binutils-2.19.51.0.14.original/bfd/elf32-ppc.c 2010-02-08 15:39:17.000000000 +0000 ++++ bfd/elf32-ppc.c 2010-02-08 16:01:59.000000000 +0000 +@@ -3309,9 +3309,13 @@ update_plt_info (bfd *abfd, struct plt_e + { + struct plt_entry *ent; + ++ if (addend < 32768) ++ sec = NULL; ++ + for (ent = *plist; ent != NULL; ent = ent->next) + if (ent->sec == sec && ent->addend == addend) + break; ++ + if (ent == NULL) + { + bfd_size_type amt = sizeof (*ent); +@@ -3500,8 +3504,7 @@ ppc_elf_check_relocs (bfd *abfd, + ppc_elf_tdata (abfd)->makes_plt_call = 1; + addend = rel->r_addend; + } +- if (!update_plt_info (abfd, ifunc, +- addend < 32768 ? NULL : got2, addend)) ++ if (!update_plt_info (abfd, ifunc, got2, addend)) + return FALSE; + + if (htab->glink == NULL) +@@ -3727,8 +3730,7 @@ ppc_elf_check_relocs (bfd *abfd, + addend = rel->r_addend; + } + h->needs_plt = 1; +- if (!update_plt_info (abfd, &h->plt.plist, +- addend < 32768 ? NULL : got2, addend)) ++ if (!update_plt_info (abfd, &h->plt.plist, got2, addend)) + return FALSE; + } + break; +@@ -3759,10 +3761,9 @@ ppc_elf_check_relocs (bfd *abfd, + case R_PPC_EMB_MRKREF: + case R_PPC_NONE: + case R_PPC_max: +- case R_PPC_RELAX32: +- case R_PPC_RELAX32PC: +- case R_PPC_RELAX32_PLT: +- case R_PPC_RELAX32PC_PLT: ++ case R_PPC_RELAX: ++ case R_PPC_RELAX_PLT: ++ case R_PPC_RELAX_PLTREL24: + break; + + /* These should only appear in dynamic objects. */ +@@ -4431,7 +4432,8 @@ ppc_elf_gc_sweep_hook (bfd *abfd, + { + bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0; + struct plt_entry *ent = find_plt_ent (ifunc, got2, addend); +- if (ent->plt.refcount > 0) ++ ++ if (ent != NULL && ent->plt.refcount > 0) + ent->plt.refcount -= 1; + continue; + } +@@ -4505,7 +4507,8 @@ ppc_elf_gc_sweep_hook (bfd *abfd, + bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0; + struct plt_entry *ent = find_plt_ent (&h->plt.plist, + got2, addend); +- if (ent->plt.refcount > 0) ++ ++ if (ent != NULL && ent->plt.refcount > 0) + ent->plt.refcount -= 1; + } + break; +@@ -4591,6 +4594,7 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT + { + Elf_Internal_Sym *locsyms = NULL; + Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd); ++ asection *got2 = bfd_get_section_by_name (ibfd, ".got2"); + + for (sec = ibfd->sections; sec != NULL; sec = sec->next) + if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section)) +@@ -4684,6 +4688,13 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT + else + continue; + ++ case R_PPC_TLSGD: ++ case R_PPC_TLSLD: ++ expecting_tls_get_addr = 2; ++ tls_set = 0; ++ tls_clear = 0; ++ break; ++ + default: + continue; + } +@@ -4691,7 +4702,8 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT + if (pass == 0) + { + if (!expecting_tls_get_addr +- || !sec->has_tls_get_addr_call) ++ || (expecting_tls_get_addr == 1 ++ && ! sec->has_tls_get_addr_call)) + continue; + + if (rel + 1 < relend +@@ -4707,6 +4719,23 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT + break; + } + ++ if (expecting_tls_get_addr) ++ { ++ struct plt_entry *ent; ++ bfd_vma addend = 0; ++ ++ if (info->shared ++ && ELF32_R_TYPE (rel[1].r_info) == R_PPC_PLTREL24) ++ addend = rel[1].r_addend; ++ ent = find_plt_ent (&htab->tls_get_addr->plt.plist, ++ got2, addend); ++ if (ent != NULL && ent->plt.refcount > 0) ++ ent->plt.refcount -= 1; ++ ++ if (expecting_tls_get_addr == 2) ++ continue; ++ } ++ + if (h != NULL) + { + tls_mask = &ppc_elf_hash_entry (h)->tls_mask; +@@ -4751,16 +4780,6 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT + *got_count -= 1; + } + +- if (expecting_tls_get_addr) +- { +- struct plt_entry *ent; +- +- ent = find_plt_ent (&htab->tls_get_addr->plt.plist, +- NULL, 0); +- if (ent != NULL && ent->plt.refcount > 0) +- ent->plt.refcount -= 1; +- } +- + *tls_mask |= tls_set; + *tls_mask &= ~tls_clear; + } +@@ -6098,28 +6117,29 @@ ppc_elf_relax_section (bfd *abfd, + { + size = 4 * ARRAY_SIZE (shared_stub_entry); + insn_offset = 12; +- stub_rtype = R_PPC_RELAX32PC; + } + else + { + size = 4 * ARRAY_SIZE (stub_entry); + insn_offset = 0; +- stub_rtype = R_PPC_RELAX32; + } + +- if (R_PPC_RELAX32_PLT - R_PPC_RELAX32 +- != R_PPC_RELAX32PC_PLT - R_PPC_RELAX32PC) +- abort (); ++ stub_rtype = R_PPC_RELAX; + if (tsec == htab->plt + || tsec == htab->glink) +- stub_rtype += R_PPC_RELAX32_PLT - R_PPC_RELAX32; ++ { ++ stub_rtype = R_PPC_RELAX_PLT; ++ if (r_type == R_PPC_PLTREL24) ++ stub_rtype = R_PPC_RELAX_PLTREL24; ++ } + + /* Hijack the old relocation. Since we need two + relocations for this use a "composite" reloc. */ + irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), + stub_rtype); + irel->r_offset = trampoff + insn_offset; +- if (r_type == R_PPC_PLTREL24) ++ if (r_type == R_PPC_PLTREL24 ++ && stub_rtype != R_PPC_RELAX_PLTREL24) + irel->r_addend = 0; + + /* Record the fixup so we don't do it again this section. */ +@@ -6289,7 +6309,7 @@ ppc_elf_relax_section (bfd *abfd, + { + /* Convert the internal relax relocs to external form. */ + for (irel = internal_relocs; irel < irelend; irel++) +- if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX32) ++ if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX) + { + unsigned long r_symndx = ELF32_R_SYM (irel->r_info); + +@@ -7461,32 +7481,36 @@ ppc_elf_relocate_section (bfd *output_bf + } + break; + +- case R_PPC_RELAX32PC_PLT: +- case R_PPC_RELAX32_PLT: +- { +- struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2, addend); +- +- if (htab->plt_type == PLT_NEW) +- relocation = (htab->glink->output_section->vma +- + htab->glink->output_offset +- + ent->glink_offset); +- else +- relocation = (htab->plt->output_section->vma +- + htab->plt->output_offset +- + ent->plt.offset); +- } +- if (r_type == R_PPC_RELAX32_PLT) +- goto relax32; +- /* Fall thru */ ++ case R_PPC_RELAX_PLT: ++ case R_PPC_RELAX_PLTREL24: ++ if (h != NULL) ++ { ++ struct plt_entry *ent; ++ bfd_vma got2_addend = 0; + +- case R_PPC_RELAX32PC: +- relocation -= (input_section->output_section->vma +- + input_section->output_offset +- + rel->r_offset - 4); ++ if (r_type == R_PPC_RELAX_PLTREL24) ++ { ++ if (info->shared) ++ got2_addend = addend; ++ addend = 0; ++ } ++ ent = find_plt_ent (&h->plt.plist, got2, got2_addend); ++ if (htab->plt_type == PLT_NEW) ++ relocation = (htab->glink->output_section->vma ++ + htab->glink->output_offset ++ + ent->glink_offset); ++ else ++ relocation = (htab->plt->output_section->vma ++ + htab->plt->output_offset ++ + ent->plt.offset); ++ } + /* Fall thru */ + +- case R_PPC_RELAX32: +- relax32: ++ case R_PPC_RELAX: ++ if (info->shared) ++ relocation -= (input_section->output_section->vma ++ + input_section->output_offset ++ + rel->r_offset - 4); + { + unsigned long t0; + unsigned long t1; +diff -rup ../binutils-2.19.51.0.14.original/bfd/elf64-ppc.c bfd/elf64-ppc.c +--- ../binutils-2.19.51.0.14.original/bfd/elf64-ppc.c 2010-02-08 15:39:17.000000000 +0000 ++++ bfd/elf64-ppc.c 2010-02-08 16:02:47.000000000 +0000 +@@ -5640,9 +5640,7 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, stru + for (ent = *ifunc; ent != NULL; ent = ent->next) + if (ent->addend == rel->r_addend) + break; +- if (ent == NULL) +- abort (); +- if (ent->plt.refcount > 0) ++ if (ent != NULL && ent->plt.refcount > 0) + ent->plt.refcount -= 1; + continue; + } +diff -rup ../binutils-2.19.51.0.14.original/include/elf/ppc.h include/elf/ppc.h +--- ../binutils-2.19.51.0.14.original/include/elf/ppc.h 2010-02-08 15:39:06.000000000 +0000 ++++ include/elf/ppc.h 2010-02-08 16:47:05.000000000 +0000 +@@ -73,10 +73,9 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type) + + #ifndef RELOC_MACROS_GEN_FUNC + /* Fake relocations for branch stubs, only used internally by ld. */ +- RELOC_NUMBER (R_PPC_RELAX32, 48) +- RELOC_NUMBER (R_PPC_RELAX32PC, 49) +- RELOC_NUMBER (R_PPC_RELAX32_PLT, 50) +- RELOC_NUMBER (R_PPC_RELAX32PC_PLT, 51) ++ RELOC_NUMBER (R_PPC_RELAX, 48) ++ RELOC_NUMBER (R_PPC_RELAX_PLT, 49) ++ RELOC_NUMBER (R_PPC_RELAX_PLTREL24, 50) + #endif + + /* Relocs added to support TLS. */ diff --git a/binutils.spec b/binutils.spec index 5ce1364..fa8bac3 100644 --- a/binutils.spec +++ b/binutils.spec @@ -17,7 +17,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.19.51.0.14 -Release: 35%{?dist} +Release: 36%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -35,6 +35,7 @@ Patch10: binutils-2.19.51.0.14-unique-is-global.patch Patch11: binutils-2.19.51.0.14-cxxfilt-java-doc.patch Patch12: binutils-2.19.51.0.14-cfi-sections.patch Patch13: binutils-2.19.51.0.14-ifunc-ld-s.patch +Patch14: binutils-2.19.51.0.14-ppc-hidden-plt-relocs.patch %if 0%{?_with_debug:1} # Define this if you want to skip the strip step and preserve debug info. @@ -111,6 +112,7 @@ to consider using libelf instead of BFD. %patch11 -p0 -b .cxxfilt-java-doc~ %patch12 -p0 -b .cfi-sections~ %patch13 -p0 -b .ifunc-ld-s~ +%patch14 -p0 -b .ppc-plt-s~ # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -378,6 +380,9 @@ exit 0 %endif # %{isnative} %changelog +* Mon Feb 8 2010 Nick Clifton 2.19.51.0.14-36 +- Fix PPC relaxation relocations. (BZ 562249, PR ld/11088) + * Mon Nov 9 2009 Jakub Jelinek 2.19.51.0.14-35 - Fix ld -s with IRELATIVE relocations. (BZ 533321, PR ld/10911)