This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH powerpc bfd] reloc fixups for little endian


OK to commit?

2006-11-21  Greg McGary  <greg@mcgary.org>

	* elf32-ppc.c (ppc_elf_relocate_section): Fixup D field
	at proper offset in little-endian mode.
	* elf64-ppc.c (ppc_elf_relocate_section): Likewise.

Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.206
diff -u -p -r1.206 elf32-ppc.c
--- bfd/elf32-ppc.c	3 Nov 2006 00:58:09 -0000	1.206
+++ bfd/elf32-ppc.c	21 Nov 2006 21:27:35 -0000
@@ -5504,6 +5504,7 @@ ppc_elf_relocate_section (bfd *output_bf
   asection *got2, *sreloc = NULL;
   bfd_vma *local_got_offsets;
   bfd_boolean ret = TRUE;
+  bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
 
 #ifdef DEBUG
   _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, "
@@ -5630,10 +5631,10 @@ ppc_elf_relocate_section (bfd *output_bf
 	      && (tls_mask & TLS_TPREL) == 0)
 	    {
 	      bfd_vma insn;
-	      insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2);
+	      insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
 	      insn &= 31 << 21;
 	      insn |= 0x3c020000;	/* addis 0,2,0 */
-	      bfd_put_32 (output_bfd, insn, contents + rel->r_offset - 2);
+	      bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset);
 	      r_type = R_PPC_TPREL16_HA;
 	      rel->r_info = ELF32_R_INFO (r_symndx, r_type);
 	    }
@@ -5677,9 +5678,10 @@ ppc_elf_relocate_section (bfd *output_bf
 	      bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
 	      r_type = R_PPC_TPREL16_LO;
 	      rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+
 	      /* Was PPC_TLS which sits on insn boundary, now
-		 PPC_TPREL16_LO which is at insn+2.  */
-	      rel->r_offset += 2;
+		 PPC_TPREL16_LO which is at low-order half-word.  */
+	      rel->r_offset += d_offset;
 	    }
 	  break;
 
@@ -5701,7 +5703,7 @@ ppc_elf_relocate_section (bfd *output_bf
 	      else
 		{
 		  bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
-		  rel->r_offset -= 2;
+		  rel->r_offset -= d_offset;
 		  r_type = R_PPC_NONE;
 		}
 	      rel->r_info = ELF32_R_INFO (r_symndx, r_type);
@@ -5750,7 +5752,7 @@ ppc_elf_relocate_section (bfd *output_bf
 		  /* OK, it checks out.  Replace the call.  */
 		  offset = rel[1].r_offset;
 		  insn1 = bfd_get_32 (output_bfd,
-				      contents + rel->r_offset - 2);
+				      contents + rel->r_offset - d_offset);
 		  if ((tls_mask & tls_gd) != 0)
 		    {
 		      /* IE */
@@ -5778,10 +5780,10 @@ ppc_elf_relocate_section (bfd *output_bf
 		      rel->r_info = ELF32_R_INFO (r_symndx, r_type);
 		      rel[1].r_info = ELF32_R_INFO (r_symndx,
 						    R_PPC_TPREL16_LO);
-		      rel[1].r_offset += 2;
+		      rel[1].r_offset += d_offset;
 		      rel[1].r_addend = rel->r_addend;
 		    }
-		  bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - 2);
+		  bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - d_offset);
 		  bfd_put_32 (output_bfd, insn2, contents + offset);
 		  if (tls_gd == 0)
 		    {
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.252
diff -u -p -r1.252 elf64-ppc.c
--- bfd/elf64-ppc.c	7 Nov 2006 03:34:52 -0000	1.252
+++ bfd/elf64-ppc.c	21 Nov 2006 21:27:36 -0000
@@ -9731,6 +9731,7 @@ ppc64_elf_relocate_section (bfd *output_
   bfd_boolean is_opd;
   /* Disabled until we sort out how ld should choose 'y' vs 'at'.  */
   bfd_boolean is_power4 = FALSE;
+  bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
 
   /* Initialize howto table if needed.  */
   if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
@@ -9960,10 +9961,10 @@ ppc64_elf_relocate_section (bfd *output_
 	      && (tls_mask & TLS_TPREL) == 0)
 	    {
 	    toctprel:
-	      insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2);
+	      insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
 	      insn &= 31 << 21;
 	      insn |= 0x3c0d0000;	/* addis 0,13,0 */
-	      bfd_put_32 (output_bfd, insn, contents + rel->r_offset - 2);
+	      bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset);
 	      r_type = R_PPC64_TPREL16_HA;
 	      if (toc_symndx != 0)
 		{
@@ -10015,8 +10016,8 @@ ppc64_elf_relocate_section (bfd *output_
 	      insn |= rtra;
 	      bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
 	      /* Was PPC64_TLS which sits on insn boundary, now
-		 PPC64_TPREL16_LO which is at insn+2.  */
-	      rel->r_offset += 2;
+		 PPC64_TPREL16_LO which is at low-order half-word.  */
+	      rel->r_offset += d_offset;
 	      r_type = R_PPC64_TPREL16_LO;
 	      if (toc_symndx != 0)
 		{
@@ -10049,7 +10050,7 @@ ppc64_elf_relocate_section (bfd *output_
 	      else
 		{
 		  bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
-		  rel->r_offset -= 2;
+		  rel->r_offset -= d_offset;
 		  r_type = R_PPC64_NONE;
 		}
 	      rel->r_info = ELF64_R_INFO (r_symndx, r_type);
@@ -10098,7 +10099,7 @@ ppc64_elf_relocate_section (bfd *output_
 		  /* OK, it checks out.  Replace the call.  */
 		  offset = rel[1].r_offset;
 		  insn1 = bfd_get_32 (output_bfd,
-				      contents + rel->r_offset - 2);
+				      contents + rel->r_offset - d_offset);
 		  insn3 = bfd_get_32 (output_bfd,
 				      contents + offset + 4);
 		  if ((tls_mask & tls_gd) != 0)
@@ -10133,7 +10134,7 @@ ppc64_elf_relocate_section (bfd *output_
 		      rel->r_info = ELF64_R_INFO (r_symndx, r_type);
 		      rel[1].r_info = ELF64_R_INFO (r_symndx,
 						    R_PPC64_TPREL16_LO);
-		      rel[1].r_offset += 2;
+		      rel[1].r_offset += d_offset;
 		    }
 		  if (insn3 == NOP
 		      || insn3 == CROR_151515 || insn3 == CROR_313131)
@@ -10142,7 +10143,7 @@ ppc64_elf_relocate_section (bfd *output_
 		      insn2 = NOP;
 		      rel[1].r_offset += 4;
 		    }
-		  bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - 2);
+		  bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - d_offset);
 		  bfd_put_32 (output_bfd, insn2, contents + offset);
 		  bfd_put_32 (output_bfd, insn3, contents + offset + 4);
 		  if (tls_gd == 0 || toc_symndx != 0)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]