This is the mail archive of the binutils@sourceware.cygnus.com 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]

Re: R_MIPS_64 broken in relocateable links



I sent in a patch for this yesterday to binutils@sourceware.  I attach
it below in case it got lost.  It's still awaiting approval.

-- 
Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/tx49-bin-ldr64.patch===============
md5sum: 55be010e980adf7c 0ebb3d4580eef908 197737
Index: binutils/bfd/ChangeLog
0a
Tue Oct 12 15:14:23 1999  Geoffrey Keating  <geoffk@cygnus.com>

	* elf32-mips.c (_bfd_mips_elf_relocate_section): Do proper
	sign-extension and big-endian compensation for
 	R_MIPS_64 even in ld -r.

.
Changed files:
binutils/bfd/ChangeLog
binutils/bfd/elf32-mips.c
md5sum: 0cc7822e898c842b 8aa6f16e037d399c 265210
--- /sloth/disk0/co/binutils-mainline/binutils/bfd/elf32-mips.c	Fri Oct  8 13:03:28 1999
+++ binutils/bfd/elf32-mips.c	Wed Oct 13 15:15:03 1999
@@ -6532,6 +6532,10 @@ _bfd_mips_elf_relocate_section (output_b
 	  Elf_Internal_Sym *sym;
 	  unsigned long r_symndx;
 
+	  if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd)
+	      && bfd_big_endian (input_bfd))
+	    rel->r_offset -= 4;
+
 	  /* Since we're just relocating, all we need to do is copy
 	     the relocations back out to the object file, unless
 	     they're against a section symbol, in which case we need
@@ -6585,6 +6589,43 @@ _bfd_mips_elf_relocate_section (output_b
 		 writing will be source of the addend in the final
 		 link.  */
 	      addend &= howto->src_mask;
+
+	      if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd))
+		/* See the comment above about using R_MIPS_64 in the 32-bit
+		   ABI.  Here, we need to update the addend.  It would be
+		   possible to get away with just using the R_MIPS_32 reloc
+		   but for endianness.  */
+		{
+		  bfd_vma sign_bits;
+		  bfd_vma low_bits;
+		  bfd_vma high_bits;
+		  
+		  if (addend & 0x80000000)
+		    sign_bits = 0xffffffff;
+		  else
+		    sign_bits = 0;
+		  
+		  /* If only a 32-bit VMA is available do two separate
+		     stores.  */
+		  if (bfd_big_endian (input_bfd))
+		    {
+		      /* Store the sign-bits (which are most significant)
+			 first.  */
+		      low_bits = sign_bits;
+		      high_bits = addend;
+		    }
+		  else
+		    {
+		      low_bits = addend;
+		      high_bits = sign_bits;
+		    }
+		  bfd_put_32 (input_bfd, low_bits, 
+			      contents + rel->r_offset);
+		  bfd_put_32 (input_bfd, high_bits, 
+			      contents + rel->r_offset + 4);
+		  continue;
+		}
+
 	      if (!mips_elf_perform_relocation (info, howto, rel, addend,
 						input_bfd,  input_section, 
 						contents, false))
============================================================

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