2011-12-13 Chung-Lin Tang <cltang@codesourcery.com>
authorChung-Lin Tang <cltang@codesourcery.com>
Tue, 13 Dec 2011 06:22:01 +0000 (06:22 +0000)
committerChung-Lin Tang <cltang@codesourcery.com>
Tue, 13 Dec 2011 06:22:01 +0000 (06:22 +0000)
* elfxx-mips.c (mips_elf_calculate_relocation): Correct
R_MIPS16_HI16/R_MIPS16_LO16 handling of two cleared lower bits,
update comments.

bfd/ChangeLog
bfd/elfxx-mips.c

index 3f1dc25..f6f8300 100644 (file)
@@ -1,3 +1,9 @@
+2011-12-13  Chung-Lin Tang  <cltang@codesourcery.com>
+
+       * elfxx-mips.c (mips_elf_calculate_relocation): Correct
+       R_MIPS16_HI16/R_MIPS16_LO16 handling of two cleared lower bits,
+       update comments.
+
 2011-12-12  Iain Sandoe  <iains@gcc.gnu.org>
 
        * mach-o.c (bfd_mach_o_read_section_32): Null-terminate sectname.
index 4e6d9b2..f493517 100644 (file)
@@ -5531,10 +5531,11 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
               12: addu    $v0,$v1
               14: move    $gp,$v0
             So the offsets of hi and lo relocs are the same, but the
-            $pc is four higher than $t9 would be, so reduce
-            both reloc addends by 4. */
+            base $pc is that used by the ADDIUPC instruction at $t9 + 4.
+            ADDIUPC clears the low two bits of the instruction address,
+            so the base is ($t9 + 4) & ~3.  */
          if (r_type == R_MIPS16_HI16)
-           value = mips_elf_high (addend + gp - p - 4);
+           value = mips_elf_high (addend + gp - ((p + 4) & ~(bfd_vma) 0x3));
          /* The microMIPS .cpload sequence uses the same assembly
             instructions as the traditional psABI version, but the
             incoming $t9 has the low bit set.  */
@@ -5557,7 +5558,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
          /* See the comment for R_MIPS16_HI16 above for the reason
             for this conditional.  */
          if (r_type == R_MIPS16_LO16)
-           value = addend + gp - p;
+           value = addend + gp - (p & ~(bfd_vma) 0x3);
          else if (r_type == R_MICROMIPS_LO16
                   || r_type == R_MICROMIPS_HI0_LO16)
            value = addend + gp - p + 3;