MIPS/BFD: Include the addend in JALX's target alignment verification
authorMaciej W. Rozycki <macro@imgtec.com>
Fri, 27 May 2016 19:43:05 +0000 (20:43 +0100)
committerMaciej W. Rozycki <macro@imgtec.com>
Fri, 27 May 2016 21:31:29 +0000 (22:31 +0100)
On RELA targets the addend can affect JALX target's alignment, so only
verify it once the whole relocation calculation has completed.

bfd/
* elfxx-mips.c (mips_elf_calculate_relocation) <R_MIPS16_26>
<R_MIPS_26, R_MICROMIPS_26_S1>: Include the addend in JALX's
target alignment verification.

ld/
* testsuite/ld-mips-elf/unaligned-jalx-addend-0.d: New test.
* testsuite/ld-mips-elf/unaligned-jalx-addend-1.d: New test.
* testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d: New
test.
* testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d: New
test.
* testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d: New
test.
* testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d: New
test.
* testsuite/ld-mips-elf/unaligned-jalx-addend-0.s: New test
source.
* testsuite/ld-mips-elf/unaligned-jalx-addend-1.s: New test
source.
* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.

12 files changed:
bfd/ChangeLog
bfd/elfxx-mips.c
ld/ChangeLog
ld/testsuite/ld-mips-elf/mips-elf.exp
ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d [new file with mode: 0644]

index 5bace1e..cefe44a 100644 (file)
@@ -1,5 +1,11 @@
 2016-05-27  Maciej W. Rozycki  <macro@imgtec.com>
 
+       * elfxx-mips.c (mips_elf_calculate_relocation) <R_MIPS16_26>
+       <R_MIPS_26, R_MICROMIPS_26_S1>: Include the addend in JALX's
+       target alignment verification.
+
+2016-05-27  Maciej W. Rozycki  <macro@imgtec.com>
+
        * elfxx-mips.c (mips_elf_calculate_relocation): Also use the
        section name if `bfd_elf_string_from_elf_section' returns an
        empty string.
index 2fff306..c2c1290 100644 (file)
@@ -5773,11 +5773,6 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
       {
        unsigned int shift;
 
-       /* Make sure the target of JALX is word-aligned.  Bit 0 must be
-          the correct ISA mode selector and bit 1 must be 0.  */
-       if (*cross_mode_jump_p && (symbol & 3) != (r_type == R_MIPS_26))
-         return bfd_reloc_outofrange;
-
        /* Shift is 2, unusually, for microMIPS JALX.  */
        shift = (!*cross_mode_jump_p && r_type == R_MICROMIPS_26_S1) ? 1 : 2;
 
@@ -5787,7 +5782,14 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
          value = _bfd_mips_elf_sign_extend (addend, 26 + shift);
        else
          value = addend;
-       value = (value + symbol) >> shift;
+       value += symbol;
+
+       /* Make sure the target of JALX is word-aligned.  Bit 0 must be
+          the correct ISA mode selector and bit 1 must be 0.  */
+       if (*cross_mode_jump_p && (value & 3) != (r_type == R_MIPS_26))
+         return bfd_reloc_outofrange;
+
+       value >>= shift;
        if (!was_local_p && h->root.root.type != bfd_link_hash_undefweak)
          overflowed_p = (value >> 26) != ((p + 4) >> (26 + shift));
        value &= howto->dst_mask;
index 1d683ac..6827732 100644 (file)
@@ -1,5 +1,23 @@
 2016-05-27  Maciej W. Rozycki  <macro@imgtec.com>
 
+       * testsuite/ld-mips-elf/unaligned-jalx-addend-0.d: New test.
+       * testsuite/ld-mips-elf/unaligned-jalx-addend-1.d: New test.
+       * testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d: New
+       test.
+       * testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d: New
+       test.
+       * testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d: New
+       test.
+       * testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d: New
+       test.
+       * testsuite/ld-mips-elf/unaligned-jalx-addend-0.s: New test
+       source.
+       * testsuite/ld-mips-elf/unaligned-jalx-addend-1.s: New test
+       source.
+       * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
+
+2016-05-27  Maciej W. Rozycki  <macro@imgtec.com>
+
        * testsuite/ld-mips-elf/reloc-local-overflow.d: New test.
        * testsuite/ld-mips-elf/reloc-local-overflow.s: Source for the
        new test.
index 0c2a93b..3fa151a 100644 (file)
@@ -184,6 +184,21 @@ run_dump_test "unaligned-jalx-mips16-1" [list [list ld $abi_ldflags(o32)]]
 run_dump_test "unaligned-jalx-micromips-0" [list [list ld $abi_ldflags(o32)]]
 run_dump_test "unaligned-jalx-micromips-1" [list [list ld $abi_ldflags(o32)]]
 
+if $has_newabi {
+    run_dump_test "unaligned-jalx-addend-0" \
+                                       [list [list ld $abi_ldflags(n32)]]
+    run_dump_test "unaligned-jalx-addend-1" \
+                                       [list [list ld $abi_ldflags(n32)]]
+    run_dump_test "unaligned-jalx-addend-mips16-0" \
+                                       [list [list ld $abi_ldflags(n32)]]
+    run_dump_test "unaligned-jalx-addend-mips16-1" \
+                                       [list [list ld $abi_ldflags(n32)]]
+    run_dump_test "unaligned-jalx-addend-micromips-0" \
+                                       [list [list ld $abi_ldflags(n32)]]
+    run_dump_test "unaligned-jalx-addend-micromips-1" \
+                                       [list [list ld $abi_ldflags(n32)]]
+}
+
 run_dump_test "unaligned-lwpc-0" [list [list ld $abi_ldflags(o32)]]
 run_dump_test "unaligned-lwpc-1" [list [list ld $abi_ldflags(o32)]]
 run_dump_test "unaligned-ldpc-0" [list [list ld $abi_ldflags(o32)]]
diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.d
new file mode 100644 (file)
index 0000000..094277b
--- /dev/null
@@ -0,0 +1,27 @@
+#name: MIPS JALX to unaligned symbol with addend 0
+#source: unaligned-jalx-addend-0.s
+#source: unaligned-insn.s -mips16
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 7700000d     jalx    1c000034 <bar2>
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 7700000c     jalx    1c000030 <bar0>
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 7700000c     jalx    1c000030 <bar0>
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 7700000e     jalx    1c000038 <bar4>
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.s b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-0.s
new file mode 100644 (file)
index 0000000..417d69a
--- /dev/null
@@ -0,0 +1,14 @@
+       .text
+       .align  4
+       .globl  foo
+       .ent    foo
+foo:
+       jal     bar0 + 4
+       jal     bar1 - 2
+       jal     bar2 - 4
+       jal     bar3 + 2
+       .end    foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.d
new file mode 100644 (file)
index 0000000..befac09
--- /dev/null
@@ -0,0 +1,29 @@
+#name: MIPS JALX to unaligned symbol with addend 1
+#source: unaligned-jalx-addend-1.s
+#source: unaligned-insn.s -mips16
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000
+#error: \A[^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\Z
diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.s b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-1.s
new file mode 100644 (file)
index 0000000..9e95bf9
--- /dev/null
@@ -0,0 +1,22 @@
+       .text
+       .align  4
+       .globl  foo
+       .ent    foo
+foo:
+       jal     bar0 + 1
+       jal     bar0 + 2
+       jal     bar0 + 3
+       jal     bar1 + 1
+       jal     bar1 + 3
+       jal     bar1 + 4
+       jal     bar2 - 1
+       jal     bar2 - 2
+       jal     bar2 - 3
+       jal     bar3 - 1
+       jal     bar3 - 3
+       jal     bar3 - 4
+       .end    foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-0.d
new file mode 100644 (file)
index 0000000..5a4eafc
--- /dev/null
@@ -0,0 +1,27 @@
+#name: microMIPS JALX to unaligned symbol with addend 0
+#source: unaligned-jalx-addend-0.s -mmicromips
+#source: unaligned-insn.s
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> f300 000d    jalx    1c000034 <bar2>
+[0-9a-f]+ <[^>]*> 0000 0000    nop
+[0-9a-f]+ <[^>]*> f300 000c    jalx    1c000030 <bar0>
+[0-9a-f]+ <[^>]*> 0000 0000    nop
+[0-9a-f]+ <[^>]*> f300 000c    jalx    1c000030 <bar0>
+[0-9a-f]+ <[^>]*> 0000 0000    nop
+[0-9a-f]+ <[^>]*> f300 000e    jalx    1c000038 <bar4>
+[0-9a-f]+ <[^>]*> 0000 0000    nop
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-micromips-1.d
new file mode 100644 (file)
index 0000000..038e46e
--- /dev/null
@@ -0,0 +1,30 @@
+#name: microMIPS JALX to unaligned symbol with addend 1
+#source: unaligned-jalx-addend-1.s -mmicromips
+#source: unaligned-insn.s
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000
+#objdump: -dr --prefix-addresses --show-raw-insn
+#error: \A[^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\Z
diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-0.d
new file mode 100644 (file)
index 0000000..3e7ac16
--- /dev/null
@@ -0,0 +1,27 @@
+#name: MIPS16 JALX to unaligned symbol with addend 0
+#source: unaligned-jalx-addend-0.s -mips16
+#source: unaligned-insn.s
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 1c18 000d    jalx    1c000034 <bar2>
+[0-9a-f]+ <[^>]*> 6500         nop
+[0-9a-f]+ <[^>]*> 1c18 000c    jalx    1c000030 <bar0>
+[0-9a-f]+ <[^>]*> 6500         nop
+[0-9a-f]+ <[^>]*> 1c18 000c    jalx    1c000030 <bar0>
+[0-9a-f]+ <[^>]*> 6500         nop
+[0-9a-f]+ <[^>]*> 1c18 000e    jalx    1c000038 <bar4>
+[0-9a-f]+ <[^>]*> 6500         nop
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d b/ld/testsuite/ld-mips-elf/unaligned-jalx-addend-mips16-1.d
new file mode 100644 (file)
index 0000000..0bd81d8
--- /dev/null
@@ -0,0 +1,30 @@
+#name: MIPS16 JALX to unaligned symbol with addend 1
+#source: unaligned-jalx-addend-1.s -mips16
+#source: unaligned-insn.s
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000
+#objdump: -dr --prefix-addresses --show-raw-insn
+#error: \A[^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\n
+#error:   [^\n]*: In function `foo':\n
+#error:   \(\.text\+0x[0-9a-f]+\): JALX to a non-word-aligned address\Z