linux-mips-fnet
[Top] [All Lists]

Re: R_MIPS_64 broken in relocateable links

To: ralf@uni-koblenz.de
Subject: Re: R_MIPS_64 broken in relocateable links
From: Geoff Keating <geoffk@ozemail.com.au>
Date: Thu, 14 Oct 1999 13:46:37 +1000
Cc: binutils@sourceware.cygnus.com, mark@codesourcery.com, linux@engr.sgi.com, linux-mips@fnet.fr, linux-mips@vger.rutgers.edu
In-reply-to: <19991013213926.A1383@uni-koblenz.de> (message from Ralf Baechle on Wed, 13 Oct 1999 21:39:26 +0200)
References: <19991013213926.A1383@uni-koblenz.de>
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))
============================================================

<Prev in Thread] Current Thread [Next in Thread>