MIPS/BFD: Discard ineligible JALR relocations right away
authorMaciej W. Rozycki <macro@imgtec.com>
Thu, 23 Feb 2017 19:26:53 +0000 (19:26 +0000)
committerMaciej W. Rozycki <macro@imgtec.com>
Thu, 23 Feb 2017 23:45:14 +0000 (23:45 +0000)
Discard R_MIPS_JALR and R_MICROMIPS_JALR relocations associated with
jumps that cannot be converted to an equivalent branch right away in
`mips_elf_calculate_relocation' rather than letting them through to
`mips_elf_perform_relocation'.  This includes cross-mode jumps which
need to flip the ISA bit or jumps to a misaligned location that cannot
be encoded with a branch, in addition to preemptible symbol references
already handled.

Cross-mode jumps are actually already rejected as the conversion is made
in `mips_elf_perform_relocation', so in this case this change only saves
some processing.  Jumps to a misaligned location are however converted,
with bits causing misalignment lost, making resulting code functionally
different even if the lone effect is avoiding an address error exception
with an instruction fetch at the jump destination requested.

Add test cases suitable, also including GAS verification to confirm that
the JALR relocations explicitly requested have indeed been output in the
intermediate objects used.

bfd/
* elfxx-mips.c (mips_elf_calculate_relocation) <R_MIPS_JALR>
<R_MICROMIPS_JALR>: Discard relocation if `cross_mode_jump_p'
or misaligned.

gas/
* testsuite/gas/mips/jalr4.d: New test.
* testsuite/gas/mips/jalr4-n32.d: New test.
* testsuite/gas/mips/jalr4-n64.d: New test.
* testsuite/gas/mips/jalr4.s: New test source.
* testsuite/gas/mips/mips.exp: Run the new tests.

ld/
* testsuite/ld-mips-elf/jalr4.dd: New test.
* testsuite/ld-mips-elf/mips-elf.exp: Run the new test.

bfd/ChangeLog
bfd/elfxx-mips.c
gas/ChangeLog
gas/testsuite/gas/mips/jalr4-n32.d [new file with mode: 0644]
gas/testsuite/gas/mips/jalr4-n64.d [new file with mode: 0644]
gas/testsuite/gas/mips/jalr4.d [new file with mode: 0644]
gas/testsuite/gas/mips/jalr4.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
ld/ChangeLog
ld/testsuite/ld-mips-elf/jalr4.dd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips-elf.exp

index 3a3ca2863189ffccd3944aceb3e0974e2a66a60c..46f5f9cfdc2b34ad831d7c29ba3628aa6e799c62 100644 (file)
@@ -1,3 +1,9 @@
+2017-02-23  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * elfxx-mips.c (mips_elf_calculate_relocation) <R_MIPS_JALR>
+       <R_MICROMIPS_JALR>: Discard relocation if `cross_mode_jump_p'
+       or misaligned.
+
 2017-02-23  Alan Modra  <amodra@gmail.com>
 
        PR 20744
index c184d2e0e01e8f23e40467d4979dbf852da4888c..ec086de76efbfa605ba428d80175aed3cd231a53 100644 (file)
@@ -6278,7 +6278,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
         when the symbol does not resolve locally.  */
       if (h != NULL && !SYMBOL_CALLS_LOCAL (info, &h->root))
        return bfd_reloc_continue;
+      /* We can't optimize cross-mode jumps either.  */
+      if (*cross_mode_jump_p)
+       return bfd_reloc_continue;
       value = symbol + addend;
+      /* Neither we can non-instruction-aligned targets.  */
+      if (r_type == R_MIPS_JALR ? (value & 3) != 0 : (value & 1) == 0)
+       return bfd_reloc_continue;
       break;
 
     case R_MIPS_PJUMP:
index 415237c6946028749a76a55b905fffce249229cb..0f46787ebacd231cd8582889605a260ddbc058b9 100644 (file)
@@ -1,3 +1,11 @@
+2017-02-23  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * testsuite/gas/mips/jalr4.d: New test.
+       * testsuite/gas/mips/jalr4-n32.d: New test.
+       * testsuite/gas/mips/jalr4-n64.d: New test.
+       * testsuite/gas/mips/jalr4.s: New test source.
+       * testsuite/gas/mips/mips.exp: Run the new tests.
+
 2017-02-23  Sheldon Lobo <sheldon.lobo@oracle.com>
 
        Add support for associating SPARC ASIs with an architecture level.
diff --git a/gas/testsuite/gas/mips/jalr4-n32.d b/gas/testsuite/gas/mips/jalr4-n32.d
new file mode 100644 (file)
index 0000000..fde29f5
--- /dev/null
@@ -0,0 +1,5 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS JALR reloc unaligned/cross-mode (n32)
+#as: -n32
+#source: jalr4.s
+#dump: jalr4.d
diff --git a/gas/testsuite/gas/mips/jalr4-n64.d b/gas/testsuite/gas/mips/jalr4-n64.d
new file mode 100644 (file)
index 0000000..b61fc23
--- /dev/null
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS JALR reloc unaligned/cross-mode (n64)
+#as: -64
+#source: jalr4.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 0320f809     jalr    t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar0
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320000[89]  jr      t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar0
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320f809     jalr    t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar1
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320000[89]  jr      t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar1
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320f809     jalr    t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar2
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320000[89]  jr      t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar2
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/jalr4.d b/gas/testsuite/gas/mips/jalr4.d
new file mode 100644 (file)
index 0000000..1a1afdd
--- /dev/null
@@ -0,0 +1,30 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS JALR reloc unaligned/cross-mode (o32)
+#as: -32
+#source: jalr4.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 0320f809     jalr    t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar0
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320000[89]  jr      t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar0
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320f809     jalr    t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar1
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320000[89]  jr      t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar1
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320f809     jalr    t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar2
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320000[89]  jr      t9
+[      ]*[0-9a-f]+: R_MIPS_JALR        bar2
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/jalr4.s b/gas/testsuite/gas/mips/jalr4.s
new file mode 100644 (file)
index 0000000..4ad6f26
--- /dev/null
@@ -0,0 +1,63 @@
+       .abicalls
+       .text
+
+       .align  2
+       .globl  foo
+       .ent    foo
+foo:
+       .reloc  1f, R_MIPS_JALR, bar0
+1:     jalr    $25
+       .reloc  1f, R_MIPS_JALR, bar0
+1:     jr      $25
+       .reloc  1f, R_MIPS_JALR, bar1
+1:     jalr    $25
+       .reloc  1f, R_MIPS_JALR, bar1
+1:     jr      $25
+       .reloc  1f, R_MIPS_JALR, bar2
+1:     jalr    $25
+       .reloc  1f, R_MIPS_JALR, bar2
+1:     jr      $25
+       .end    foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
+
+       .align  2
+       .globl  bar0
+       .ent    bar0
+bar0:
+       .insn
+       .end    bar0
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
+
+       .align  2
+       .globl  bar1
+       .ent    bar1
+       .space  2
+bar1:
+       .insn
+       .end    bar1
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
+
+       .set    mips64r2
+       .set    mips16
+       .align  2
+       .globl  bar2
+       .ent    bar2
+       .byte   0
+bar2:
+       .insn
+       .end    bar2
+       .set    nomips16
+       .set    mips0
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
index bef710635bbbe61ef93609572cd7fc35ccda0cf1..591af507a27c3b9cd016828c75045c2c3d86f2a7 100644 (file)
@@ -1182,13 +1182,21 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "jalr2"
     run_dump_test_arches "jalr3"       [mips_arch_list_matching mips1 \
                                            !micromips]
+    run_dump_test_arches "jalr4"       [mips_arch_list_matching mips1 \
+                                           !micromips]
     if $has_newabi {
        run_dump_test_arches "jalr3-n32" \
                                        [mips_arch_list_matching mips3 \
                                            !micromips]
+       run_dump_test_arches "jalr4-n32" \
+                                       [mips_arch_list_matching mips3 \
+                                           !micromips]
        run_dump_test_arches "jalr3-n64" \
                                        [mips_arch_list_matching mips3 \
                                            !micromips]
+       run_dump_test_arches "jalr4-n64" \
+                                       [mips_arch_list_matching mips3 \
+                                           !micromips]
     }
 
     run_dump_test_arches "aent"                [mips_arch_list_matching mips1]
index 8807c909f22778297ec940b23f578101df4bd653..3e88456a17966b5d72294cb3f3c9e0e2effa6e5e 100644 (file)
@@ -1,3 +1,8 @@
+2017-02-23  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * testsuite/ld-mips-elf/jalr4.dd: New test.
+       * testsuite/ld-mips-elf/mips-elf.exp: Run the new test.
+
 2017-02-23  Alan Modra  <amodra@gmail.com>
 
        PR 20744
diff --git a/ld/testsuite/ld-mips-elf/jalr4.dd b/ld/testsuite/ld-mips-elf/jalr4.dd
new file mode 100644 (file)
index 0000000..8e41756
--- /dev/null
@@ -0,0 +1,19 @@
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 0411000f     bal     0+000040 <bar0>
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 1000000d     b       0+000040 <bar0>
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320f809     jalr    t9
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 03200008     jr      t9
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 0320f809     jalr    t9
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 03200008     jr      t9
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
+       \.\.\.
+       \.\.\.
+       \.\.\.
index 7fa11c5989d1ad2d9bda5c4b392a842ef0835234..dab0e0fbab95672f9584af8e8586d2883e7c125a 100644 (file)
@@ -999,7 +999,14 @@ foreach { abi } $abis {
            "$abi_asflags($abi)" \
            [list ../../../gas/testsuite/gas/mips/jalr3.s] \
            [list "objdump -d jalr3.dd"] \
-           "jalr3-${abi}"]]
+           "jalr3-${abi}"] \
+       [list \
+           "MIPS JALR reloc unaligned/cross-mode link test ($abi)" \
+           "$abi_ldflags($abi) -T jalr3.ld" "" \
+           "$abi_asflags($abi)" \
+           [list ../../../gas/testsuite/gas/mips/jalr4.s] \
+           [list "objdump {-d --prefix-addresses --show-raw-insn} jalr4.dd"] \
+           "jalr4-${abi}"]]
 }
 
 proc build_mips_plt_lib { abi } {