MIPS/gas: Fix misaligned address errors to disregard ISA mode bit
authorFaraz Shahbazker <fshahbazker@wavecomp.com>
Tue, 13 Aug 2019 05:32:20 +0000 (05:32 +0000)
committerFaraz Shahbazker <fshahbazker@wavecomp.com>
Mon, 19 Aug 2019 20:43:51 +0000 (13:43 -0700)
gas/
* config/tc-mips.c (fix_bad_misaligned_address): New function.
(fix_validate_branch): Call fix_bad_misaligned address_to
calculate the target address.
(md_apply_fix): Likewise.
(md_convert_frag): Update misaligned address calculation to
disregard ISA mode bit.

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

index cb81de46c0b10ec3434eb59081ce4e50c4f35f01..966bc1727104f223e7196a34c028f38a4fd161e3 100644 (file)
@@ -1,3 +1,12 @@
+2019-08-19  Faraz Shahbazker  <fshahbazker@wavecomp.com>
+
+       * config/tc-mips.c (fix_bad_misaligned_address): New function.
+       (fix_validate_branch): Call fix_bad_misaligned address_to
+       calculate the target address.
+       (md_apply_fix): Likewise.
+       (md_convert_frag): Update misaligned address calculation to
+       disregard ISA mode bit.
+
 2019-08-19  Faraz Shahbazker  <fshahbazker@wavecomp.com>
 
        * config/tc-mips.c (mips_move_labels): Retain ISA mode bit
index 38a1b8c7a55cff43c283bfbd73c3c70059f3360b..a386d11f6c2451430936500c06754c2bfb5c2c06 100644 (file)
@@ -15743,6 +15743,24 @@ fix_bad_misaligned_branch_p (fixS *fixP)
   return (val & 0x3) != isa_bit;
 }
 
+/* Calculate the relocation target by masking off ISA mode bit before
+   combining symbol and addend.  */
+
+static valueT
+fix_bad_misaligned_address (fixS *fixP)
+{
+  valueT val;
+  valueT off;
+  unsigned isa_mode;
+  gas_assert (fixP != NULL && fixP->fx_addsy != NULL);
+  val = S_GET_VALUE (fixP->fx_addsy);
+  off = fixP->fx_offset;
+  isa_mode = (ELF_ST_IS_COMPRESSED (S_GET_OTHER (fixP->fx_addsy))
+             ? 1 : 0);
+
+  return ((val & ~isa_mode) + off);
+}
+
 /* Make the necessary checks on a regular MIPS branch pointed to by FIXP
    and its calculated value VAL.  */
 
@@ -15759,7 +15777,7 @@ fix_validate_branch (fixS *fixP, valueT val)
   else if (fix_bad_misaligned_branch_p (fixP))
     as_bad_where (fixP->fx_file, fixP->fx_line,
                  _("branch to misaligned address (0x%lx)"),
-                 (long) (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset));
+                 (long) fix_bad_misaligned_address (fixP));
   else if (HAVE_IN_PLACE_ADDENDS && (fixP->fx_offset & 0x3) != 0)
     as_bad_where (fixP->fx_file, fixP->fx_line,
                  _("cannot encode misaligned addend "
@@ -15898,8 +15916,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        else if (fix_bad_misaligned_jump_p (fixP, shift))
          as_bad_where (fixP->fx_file, fixP->fx_line,
                        _("jump to misaligned address (0x%lx)"),
-                       (long) (S_GET_VALUE (fixP->fx_addsy)
-                               + fixP->fx_offset));
+                       (long) fix_bad_misaligned_address (fixP));
        else if (HAVE_IN_PLACE_ADDENDS
                 && (fixP->fx_offset & ((1 << shift) - 1)) != 0)
          as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -16153,7 +16170,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
               && (fixP->fx_offset & 0x1) != 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("branch to misaligned address (0x%lx)"),
-                     (long) (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset));
+                     (long) fix_bad_misaligned_address (fixP));
       else if (HAVE_IN_PLACE_ADDENDS && (fixP->fx_offset & 0x1) != 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("cannot encode misaligned addend "
@@ -19000,7 +19017,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
              else if ((fragp->fr_offset & 0x1) != 0)
                as_bad_where (fragp->fr_file, fragp->fr_line,
                              _("branch to misaligned address (0x%lx)"),
-                             (long) val);
+                             (long) (resolve_symbol_value (fragp->fr_symbol)
+                                     + (fragp->fr_offset & ~1)));
            }
 
          val = mips16_pcrel_val (fragp, pcrel_op, val, 0);