From 8ef28f50d1146c6fe9b07400493dbb9a2f4f1e22 Mon Sep 17 00:00:00 2001 From: Nicholas Clifton Date: Dec 17 2009 17:41:35 +0000 Subject: Apply patch for PR 11088. (BZ 544149) --- diff --git a/binutils-2.20.51.0.2-ppc64-hidden-plt-relocs.patch b/binutils-2.20.51.0.2-ppc64-hidden-plt-relocs.patch new file mode 100644 index 0000000..b1e836a --- /dev/null +++ b/binutils-2.20.51.0.2-ppc64-hidden-plt-relocs.patch @@ -0,0 +1,325 @@ +diff -rup ../binutils-2.20.51.0.2.original/bfd/ChangeLog bfd/ChangeLog +--- ../binutils-2.20.51.0.2.original/bfd/ChangeLog 2009-12-17 16:08:07.000000000 +0000 ++++ bfd/ChangeLog 2009-12-17 16:27:06.000000000 +0000 +@@ -1,3 +1,25 @@ ++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-10-09 Tristan Gingold + + * mach-o.c (bfd_mach_o_section_get_entry_size): Moved. +diff -rup ../binutils-2.20.51.0.2.original/bfd/elf32-ppc.c bfd/elf32-ppc.c +--- ../binutils-2.20.51.0.2.original/bfd/elf32-ppc.c 2009-12-17 16:08:07.000000000 +0000 ++++ bfd/elf32-ppc.c 2009-12-17 16:23:22.000000000 +0000 +@@ -3323,6 +3323,8 @@ 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; +@@ -3508,8 +3510,7 @@ ppc_elf_check_relocs (bfd *abfd, + if (info->shared) + 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; + } + } +@@ -3748,8 +3749,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; +@@ -3780,10 +3780,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. */ +@@ -4486,7 +4485,7 @@ ppc_elf_gc_sweep_hook (bfd *abfd, + struct plt_entry *ent; + + ent = find_plt_ent (&h->plt.plist, NULL, 0); +- if (ent->plt.refcount > 0) ++ if (ent != NULL && ent->plt.refcount > 0) + ent->plt.refcount -= 1; + } + } +@@ -4582,9 +4581,11 @@ ppc_elf_tls_setup (bfd *obfd, + && tga->root.type == bfd_link_hash_undefweak))) + { + struct plt_entry *ent; +- ent = find_plt_ent (&tga->plt.plist, NULL, 0); +- if (ent != NULL +- && ent->plt.refcount > 0) ++ ++ for (ent = tga->plt.plist; ent != NULL; ent = ent->next) ++ if (ent->plt.refcount > 0) ++ break; ++ if (ent != NULL) + { + tga->root.type = bfd_link_hash_indirect; + tga->root.u.i.link = &opt->root; +@@ -4669,6 +4670,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)) +@@ -4762,6 +4764,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; + } +@@ -4769,7 +4778,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 +@@ -4785,6 +4795,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; +@@ -4829,16 +4856,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; + } +@@ -6239,28 +6256,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. */ +@@ -6430,7 +6448,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); + +@@ -7655,12 +7673,20 @@ ppc_elf_relocate_section (bfd *output_bf + } + break; + +- case R_PPC_RELAX32PC_PLT: +- case R_PPC_RELAX32_PLT: ++ case R_PPC_RELAX_PLT: ++ case R_PPC_RELAX_PLTREL24: + if (h != NULL) + { +- struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2, +- info->shared ? addend : 0); ++ struct plt_entry *ent; ++ bfd_vma got2_addend = 0; ++ ++ 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 +@@ -7670,18 +7696,13 @@ ppc_elf_relocate_section (bfd *output_bf + + htab->plt->output_offset + + ent->plt.offset); + } +- if (r_type == R_PPC_RELAX32_PLT) +- goto relax32; +- /* Fall thru */ +- +- case R_PPC_RELAX32PC: +- relocation -= (input_section->output_section->vma +- + input_section->output_offset +- + rel->r_offset - 4); + /* 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.20.51.0.2.original/bfd/elf64-ppc.c bfd/elf64-ppc.c +--- ../binutils-2.20.51.0.2.original/bfd/elf64-ppc.c 2009-12-17 16:08:07.000000000 +0000 ++++ bfd/elf64-ppc.c 2009-12-17 16:10:41.000000000 +0000 +@@ -5866,9 +5866,7 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, stru + for (ent = h->plt.plist; 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; + } + break; +diff -rup ../binutils-2.20.51.0.2.original/include/elf/ChangeLog include/elf/ChangeLog +--- ../binutils-2.20.51.0.2.original/include/elf/ChangeLog 2009-12-17 16:07:45.000000000 +0000 ++++ include/elf/ChangeLog 2009-12-17 16:12:12.000000000 +0000 +@@ -1,3 +1,9 @@ ++2009-12-17 Alan Modra ++ ++ * ppc.h (R_PPC_RELAX32, R_PPC_RELAX32PC, R_PPC_RELAX32_PLT, ++ R_PPC_RELAX32PC_PLT): Delete. ++ (R_PPC_RELAX, R_PPC_RELAX_PLT, R_PPC_RELAX_PLTREL24): Define. ++ + 2009-09-29 DJ Delorie + + * rx.h: New file. +@@ -34,11 +40,11 @@ + R_push, R_const, R_add, R_sub, R_mult, R_div, R_mod, R_lshift, + R_rshift, R_and, R_or, R_xor, R_land, R_lor, R_len, R_neg, R_comp, + R_page, R_hwpage, R_addr, R_pltpc, R_got. +- ++ + 2009-08-09 Michael Eager + + * elf/common.h: Define EM_resnnn reserved values. Add EM_AVR32, +- EM_STM8, EM_TILE64, EM_TILEPRO. Change EM_MICROBLAZE. ++ EM_STM8, EM_TILE64, EM_TILEPRO. Change EM_MICROBLAZE. + + 2009-08-06 Michael Eager + +diff -rup ../binutils-2.20.51.0.2.original/include/elf/ppc.h include/elf/ppc.h +--- ../binutils-2.20.51.0.2.original/include/elf/ppc.h 2009-12-17 16:07:45.000000000 +0000 ++++ include/elf/ppc.h 2009-12-17 16:12:51.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 dfc050f..9ca31b9 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.20.51.0.2 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -35,6 +35,7 @@ Patch09: binutils-2.20.51.0.2-ifunc-ld-s.patch Patch10: binutils-2.20.51.0.2-lwp.patch Patch11: binutils-2.20.51.0.2-enable-gold.patch Patch12: binutils-2.20.51.0.2-gas-expr.patch +Patch13: binutils-2.20.51.0.2-ppc64-hidden-plt-relocs.patch %define gold_arches %ix86 x86_64 @@ -128,6 +129,7 @@ to consider using libelf instead of BFD. %patch10 -p0 -b .lwp~ %patch11 -p0 -b .enable-gold~ %patch12 -p0 -b .gas-expr~ +%patch13 -p0 -b .hidden-plt~ # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -425,6 +427,9 @@ exit 0 %endif # %{isnative} %changelog +* Thu Dec 17 2009 Nick Clifton - 2.20.51.0.2-10 +- Apply patch for PR 11088. (BZ 544149) + * Wed Dec 9 2009 Nick Clifton - 2.20.51.0.2-9 - Apply patch for PR 10856. (BZ 544358)