diff options
author | Jeremy Lainé <jeremy.laine@bolloretelecom.eu> | 2009-12-28 22:09:58 +0100 |
---|---|---|
committer | Jeremy Lainé <jeremy.laine@bolloretelecom.eu> | 2009-12-28 22:09:58 +0100 |
commit | b9368e612020a4f11e4abbab78da967c0e409058 (patch) | |
tree | 31bee7b2a20e63052c939ba45d442582f49c2f3a /recipes/binutils | |
parent | 28bd169f44e2ab8c5a6164d2a10aa344a8c8c576 (diff) |
binutils-2.20: add patch for ld segfault on powerpc
Diffstat (limited to 'recipes/binutils')
-rw-r--r-- | recipes/binutils/binutils-2.20/binutils-powerpc-pr11088.patch | 275 | ||||
-rw-r--r-- | recipes/binutils/binutils_2.20.bb | 7 |
2 files changed, 280 insertions, 2 deletions
diff --git a/recipes/binutils/binutils-2.20/binutils-powerpc-pr11088.patch b/recipes/binutils/binutils-2.20/binutils-powerpc-pr11088.patch new file mode 100644 index 0000000000..d5be1760e0 --- /dev/null +++ b/recipes/binutils/binutils-2.20/binutils-powerpc-pr11088.patch @@ -0,0 +1,275 @@ +Fix ld segfault when compiling Qt 4.6.0 on powerpc. See: + +http://sourceware.org/bugzilla/show_bug.cgi?id=11088 + +=================================================================== +RCS file: /cvs/src/src/include/elf/ppc.h,v +retrieving revision 1.26 +retrieving revision 1.27 +diff -u -r1.26 -r1.27 +--- src/include/elf/ppc.h 2009/09/21 11:51:01 1.26 ++++ src/include/elf/ppc.h 2009/12/17 05:45:25 1.27 +@@ -73,10 +73,9 @@ + + #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. */ +=================================================================== +RCS file: /cvs/src/src/bfd/elf32-ppc.c,v +retrieving revision 1.272 +retrieving revision 1.273 +diff -u -r1.272 -r1.273 +--- src/bfd/elf32-ppc.c 2009/12/11 13:42:02 1.272 ++++ src/bfd/elf32-ppc.c 2009/12/17 05:45:25 1.273 +@@ -3323,6 +3323,8 @@ + { + 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 @@ + 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 @@ + 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 @@ + 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 @@ + 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; + } + } +@@ -4534,7 +4533,7 @@ + if (r_type == R_PPC_PLTREL24 && info->shared) + addend = rel->r_addend; + 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; +@@ -4582,9 +4581,10 @@ + && 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 +4669,7 @@ + { + 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 +4763,13 @@ + 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 +4777,8 @@ + 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 +4794,23 @@ + 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 +4855,6 @@ + *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 +6255,28 @@ + { + 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 +6446,7 @@ + { + /* 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); + +@@ -7669,12 +7685,20 @@ + } + 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 +@@ -7684,18 +7708,14 @@ + + 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_RELAX: ++ if (info->shared) ++ relocation -= (input_section->output_section->vma ++ + input_section->output_offset ++ + rel->r_offset - 4); + +- case R_PPC_RELAX32: +- relax32: + { + unsigned long t0; + unsigned long t1; diff --git a/recipes/binutils/binutils_2.20.bb b/recipes/binutils/binutils_2.20.bb index 5398688cfb..6961377275 100644 --- a/recipes/binutils/binutils_2.20.bb +++ b/recipes/binutils/binutils_2.20.bb @@ -2,7 +2,7 @@ require binutils.inc LICENSE = "GPLv3" INC_PR = "r1" -PR = "${INC_PR}.2" +PR = "${INC_PR}.3" SRC_URI = "\ ${GNU_MIRROR}/binutils/binutils-${PV}.tar.bz2 \ @@ -17,4 +17,7 @@ SRC_URI = "\ " # powerpc patches -SRC_URI += "file://binutils-2.16.1-e300c2c3.patch;patch=1" +SRC_URI += "\ + file://binutils-2.16.1-e300c2c3.patch;patch=1 \ + file://binutils-powerpc-pr11088.patch;patch=1 \ + " |