summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.patch132
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;
+