* elf32-mips.c (_bfd_mips_elf_relocate_section): Do proper
authorGeoffrey Keating <geoffk@geoffk.org>
Sat, 11 Mar 2000 02:23:10 +0000 (02:23 +0000)
committerGeoffrey Keating <geoffk@geoffk.org>
Sat, 11 Mar 2000 02:23:10 +0000 (02:23 +0000)
sign-extension and big-endian compensation for
R_MIPS_64 even in ld -r.

bfd/ChangeLog
bfd/elf32-mips.c

index aac6e3df2beedfaa16e20a0f9d8859ae995dddbe..773cf69b02f70c936639f23509b8704819a4360a 100644 (file)
@@ -1,3 +1,9 @@
+2000-03-10  Geoff 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.
+
 2000-03-10  Geoffrey Keating  <geoffk@cygnus.com>
 
        * elf32-mips.c (mips_elf_next_relocation): Rename from
index 671dcb1d91ad31248e471909f57055af6e097f99..d91bab9726841e2e304b21e4d74a8381a2e40639 100644 (file)
@@ -6668,6 +6668,10 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          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
@@ -6724,6 +6728,43 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                 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 & 0x80000000u)
+                   sign_bits = 0xffffffffu;
+                 else
+                   sign_bits = 0;
+                 
+                 /* If we don't know that we have a 64-bit type,
+                    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))
@@ -6818,13 +6859,13 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          bfd_vma low_bits;
          bfd_vma high_bits;
 
-         if (value & 0x80000000)
-           sign_bits = 0xffffffff;
+         if (value & 0x80000000u)
+           sign_bits = 0xffffffffu;
          else
            sign_bits = 0;
 
-         /* If only a 32-bit VMA is available do two separate
-            stores.  */
+         /* If we don't know that we have a 64-bit type,
+            do two separate stores.  */
          if (bfd_big_endian (input_bfd))
            {
              /* Undo what we did above.  */