MIPS/GAS: Correct BFD_RELOC_MIPS_18_PCREL_S3 calculation
authorMaciej W. Rozycki <macro@imgtec.com>
Tue, 21 Jun 2016 17:54:16 +0000 (18:54 +0100)
committerMaciej W. Rozycki <macro@imgtec.com>
Tue, 21 Jun 2016 21:58:50 +0000 (22:58 +0100)
The PC-relative R_MIPS_PC18_S3 relocation and consequently its BFD
internal BFD_RELOC_MIPS_18_PCREL_S3 representation is calculated from
the address of the aligned doubleword containing the location being
relocated: (sign_extend(A) + S - (P & ~0x7)) >> 3 rather than the
address of the location itself.  Reflect this in calculations made by
GAS so that the relocated field is set correctly if resolved by GAS,
such as with local symbols in the same section which do not require
relocations to be propagated to the link stage.

gas/
* config/tc-mips.c (md_pcrel_from) <BFD_RELOC_MIPS_18_PCREL_S3>:
Calculate relocation from the containing aligned doubleword.
(tc_gen_reloc) <BFD_RELOC_MIPS_18_PCREL_S3>: Calculate the
addend from the containing aligned doubleword.

gas/ChangeLog
gas/config/tc-mips.c

index 1e88b21e0c06abe537c6bfb2637229614c3c3fcb..45a505434e74d0f9ea82737917df836ccc8ab514 100644 (file)
@@ -1,3 +1,10 @@
+2016-06-21  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * config/tc-mips.c (md_pcrel_from) <BFD_RELOC_MIPS_18_PCREL_S3>:
+       Calculate relocation from the containing aligned doubleword.
+       (tc_gen_reloc) <BFD_RELOC_MIPS_18_PCREL_S3>: Calculate the
+       addend from the containing aligned doubleword.
+
 2016-06-21  Maciej W. Rozycki  <macro@imgtec.com>
 
        * config/tc-mips.c (mips_force_relocation): Use `file_mips_opts'
index ed64b6893641e4940c91c531ed98ae66fd681113..74f7e00560768e0fa23adc8baeb1f9de9c48eead 100644 (file)
@@ -14606,6 +14606,11 @@ md_pcrel_from (fixS *fixP)
       /* Return the address of the delay slot.  */
       return addr + 4;
 
+    case BFD_RELOC_MIPS_18_PCREL_S3:
+      /* Return the aligned address of the doubleword containing
+         the instruction.  */
+      return addr & ~7;
+
     default:
       return addr;
     }
@@ -17224,7 +17229,15 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 
       /* At this point, fx_addnumber is "symbol offset - pcrel address".
         Relocations want only the symbol offset.  */
-      reloc->addend = fixp->fx_addnumber + reloc->address;
+      switch (fixp->fx_r_type)
+       {
+       case BFD_RELOC_MIPS_18_PCREL_S3:
+         reloc->addend = fixp->fx_addnumber + (reloc->address & ~7);
+         break;
+       default:
+         reloc->addend = fixp->fx_addnumber + reloc->address;
+         break;
+       }
     }
   else if (HAVE_IN_PLACE_ADDENDS
           && fixp->fx_r_type == BFD_RELOC_MICROMIPS_JMP