diff options
Diffstat (limited to 'sys-devel/binutils/files/2.14/binutils-2.14.90.0.4-ppc64-prelink.patch')
-rw-r--r-- | sys-devel/binutils/files/2.14/binutils-2.14.90.0.4-ppc64-prelink.patch | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/sys-devel/binutils/files/2.14/binutils-2.14.90.0.4-ppc64-prelink.patch b/sys-devel/binutils/files/2.14/binutils-2.14.90.0.4-ppc64-prelink.patch new file mode 100644 index 000000000000..db21d8899ae4 --- /dev/null +++ b/sys-devel/binutils/files/2.14/binutils-2.14.90.0.4-ppc64-prelink.patch @@ -0,0 +1,132 @@ +2003-06-17 Alan Modra <amodra@bigpond.net.au> + + * elf64-ppc.c (ppc64_elf_relocate_section): Correct pcrel section zero. + +2003-06-16 Alan Modra <amodra@bigpond.net.au> + + * elf64-ppc.c (ppc64_elf_relocate_section): When optimizing toctprel + tls, check that a TOC16_DS or TOC16_LO_DS reloc isn't pointing to a + dtprel entry. Ensure TLS_LD DTPMOD reloc has a zero addend. Write + got section for RELATIVE relocs. Fix wrong comment. Change condition + under which dynamic relocs update the section contents. + +--- bfd/elf64-ppc.c 10 Jun 2003 07:44:09 -0000 1.101 ++++ bfd/elf64-ppc.c 16 Jun 2003 10:50:22 -0000 1.102 +@@ -7153,7 +7153,11 @@ ppc64_elf_relocate_section (output_bfd, + tls_mask = *toc_tls; + if (r_type == R_PPC64_TOC16_DS + || r_type == R_PPC64_TOC16_LO_DS) +- goto toctprel; ++ { ++ if (tls_mask != 0 ++ && (tls_mask & (TLS_DTPREL | TLS_TPREL)) == 0) ++ goto toctprel; ++ } + else + { + /* If we found a GD reloc pair, then we might be +@@ -7176,11 +7180,11 @@ ppc64_elf_relocate_section (output_bfd, + + case R_PPC64_GOT_TPREL16_DS: + case R_PPC64_GOT_TPREL16_LO_DS: +- toctprel: + if (tls_mask != 0 + && (tls_mask & TLS_TPREL) == 0) + { + bfd_vma insn; ++ toctprel: + insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2); + insn &= 31 << 21; + insn |= 0x3c0d0000; /* addis 0,13,0 */ +@@ -7653,6 +7657,7 @@ ppc64_elf_relocate_section (output_bfd, + outrel.r_offset = (htab->sgot->output_section->vma + + htab->sgot->output_offset + + off); ++ outrel.r_addend = rel->r_addend; + if (tls_type & (TLS_LD | TLS_GD)) + { + outrel.r_addend = 0; +@@ -7665,6 +7670,7 @@ ppc64_elf_relocate_section (output_bfd, + bfd_elf64_swap_reloca_out (output_bfd, + &outrel, loc); + outrel.r_offset += 8; ++ outrel.r_addend = rel->r_addend; + outrel.r_info + = ELF64_R_INFO (indx, R_PPC64_DTPREL64); + } +@@ -7674,11 +7680,18 @@ ppc64_elf_relocate_section (output_bfd, + else if (tls_type == (TLS_TLS | TLS_TPREL)) + outrel.r_info = ELF64_R_INFO (indx, R_PPC64_TPREL64); + else if (indx == 0) +- outrel.r_info = ELF64_R_INFO (indx, R_PPC64_RELATIVE); ++ { ++ outrel.r_info = ELF64_R_INFO (indx, R_PPC64_RELATIVE); ++ ++ /* Write the .got section contents for the sake ++ of prelink. */ ++ loc = htab->sgot->contents + off; ++ bfd_put_64 (output_bfd, outrel.r_addend + relocation, loc); ++ } + else + outrel.r_info = ELF64_R_INFO (indx, R_PPC64_GLOB_DAT); +- outrel.r_addend = rel->r_addend; +- if (indx == 0) ++ ++ if (indx == 0 && tls_type != (TLS_TLS | TLS_LD)) + { + outrel.r_addend += relocation; + if (tls_type & (TLS_GD | TLS_DTPREL | TLS_TPREL)) +@@ -7921,8 +7934,6 @@ ppc64_elf_relocate_section (output_bfd, + or this is an opd section reloc which must point + at a local function. */ + outrel.r_addend += relocation; +- /* ??? why? */ +- relocate = TRUE; + if (r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC) + { + if (is_opd && h != NULL) +@@ -7940,6 +7951,12 @@ ppc64_elf_relocate_section (output_bfd, + unresolved_reloc = FALSE; + } + outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE); ++ ++ /* We need to relocate .opd contents for ld.so. ++ Prelink also wants simple and consistent rules ++ for relocs. This make all RELATIVE relocs have ++ *r_offset equal to r_addend. */ ++ relocate = TRUE; + } + else + { +@@ -7981,9 +7998,29 @@ ppc64_elf_relocate_section (output_bfd, + + /* If this reloc is against an external symbol, it will + be computed at runtime, so there's no need to do +- anything now. */ ++ anything now. However, for the sake of prelink ensure ++ that the section contents are a known value. */ + if (! relocate) +- continue; ++ { ++ unresolved_reloc = FALSE; ++ /* The value chosen here is quite arbitrary as ld.so ++ ignores section contents except for the special ++ case of .opd where the contents might be accessed ++ before relocation. Choose zero, as that won't ++ cause reloc overflow. */ ++ relocation = 0; ++ addend = 0; ++ /* Use *r_offset == r_addend for R_PPC64_ADDR64 relocs ++ to improve backward compatibility with older ++ versions of ld. */ ++ if (r_type == R_PPC64_ADDR64) ++ addend = outrel.r_addend; ++ /* Adjust pc_relative relocs to have zero in *r_offset. */ ++ else if (ppc64_elf_howto_table[(int) r_type]->pc_relative) ++ addend = (input_section->output_section->vma ++ + input_section->output_offset ++ + rel->r_offset); ++ } + } + break; + |