MIPS/GAS: Correct branch relaxation for weak symbols
authorMaciej W. Rozycki <macro@imgtec.com>
Sat, 9 Apr 2016 10:59:36 +0000 (11:59 +0100)
committerMaciej W. Rozycki <macro@imgtec.com>
Wed, 13 Apr 2016 12:38:50 +0000 (13:38 +0100)
Weak symbols can be preempted at link time so always choose the longer
sequence in branch relaxation, according to the relaxation level chosen,
so that any symbol finally used as the branch target is reachable.

2016-04-13  Maciej W. Rozycki  <macro@imgtec.com>
            Andrew Bennett  <andrew.bennett@imgtec.com>

gas/
* config/tc-mips.c (relaxed_branch_length): Use the long
sequence where the target is a weak symbol.
(relaxed_micromips_32bit_branch_length): Likewise.
(relaxed_micromips_16bit_branch_length): Likewise.
* testsuite/gas/mips/branch-weak-1.d: New test.
* testsuite/gas/mips/branch-weak-2.d: New test.
* testsuite/gas/mips/branch-weak-3.d: New test.
* testsuite/gas/mips/branch-weak-4.d: New test.
* testsuite/gas/mips/branch-weak-5.d: New test.
* testsuite/gas/mips/branch-weak.l: New stderr output.
* testsuite/gas/mips/branch-weak.s: New test source.
* testsuite/gas/mips/mips.exp: Run the new tests.

gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/gas/mips/branch-weak-1.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-weak-2.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-weak-3.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-weak-4.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-weak-5.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-weak.l [new file with mode: 0644]
gas/testsuite/gas/mips/branch-weak.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp

index b5548b3..46605f9 100644 (file)
@@ -1,4 +1,20 @@
 2016-04-13  Maciej W. Rozycki  <macro@imgtec.com>
+           Andrew Bennett  <andrew.bennett@imgtec.com>
+
+       * config/tc-mips.c (relaxed_branch_length): Use the long
+       sequence where the target is a weak symbol.
+       (relaxed_micromips_32bit_branch_length): Likewise.
+       (relaxed_micromips_16bit_branch_length): Likewise.
+       * testsuite/gas/mips/branch-weak-1.d: New test.
+       * testsuite/gas/mips/branch-weak-2.d: New test.
+       * testsuite/gas/mips/branch-weak-3.d: New test.
+       * testsuite/gas/mips/branch-weak-4.d: New test.
+       * testsuite/gas/mips/branch-weak-5.d: New test.
+       * testsuite/gas/mips/branch-weak.l: New stderr output.
+       * testsuite/gas/mips/branch-weak.s: New test source.
+       * testsuite/gas/mips/mips.exp: Run the new tests.
+
+2016-04-13  Maciej W. Rozycki  <macro@imgtec.com>
 
        * config/tc-mips.c (relaxed_branch_length): Use the long
        sequence where the distance cannot be determined.
index dba147a..118b91d 100644 (file)
@@ -16798,6 +16798,7 @@ relaxed_branch_length (fragS *fragp, asection *sec, int update)
 
   if (fragp
       && S_IS_DEFINED (fragp->fr_symbol)
+      && !S_IS_WEAK (fragp->fr_symbol)
       && sec == S_GET_SEGMENT (fragp->fr_symbol))
     {
       addressT addr;
@@ -16861,6 +16862,7 @@ relaxed_micromips_32bit_branch_length (fragS *fragp, asection *sec, int update)
 
   if (fragp
       && S_IS_DEFINED (fragp->fr_symbol)
+      && !S_IS_WEAK (fragp->fr_symbol)
       && sec == S_GET_SEGMENT (fragp->fr_symbol))
     {
       addressT addr;
@@ -16952,6 +16954,7 @@ relaxed_micromips_16bit_branch_length (fragS *fragp, asection *sec, int update)
 
   if (fragp
       && S_IS_DEFINED (fragp->fr_symbol)
+      && !S_IS_WEAK (fragp->fr_symbol)
       && sec == S_GET_SEGMENT (fragp->fr_symbol))
     {
       addressT addr;
diff --git a/gas/testsuite/gas/mips/branch-weak-1.d b/gas/testsuite/gas/mips/branch-weak-1.d
new file mode 100644 (file)
index 0000000..859a2ca
--- /dev/null
@@ -0,0 +1,15 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS branch to a weak symbol
+#as: -32 --defsym align=12
+#source: branch-weak.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 1000ffff     b       00000000 <foo>
+[      ]*[0-9a-f]+: R_MIPS_PC16        bar
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
+[0-9a-f]+ <[^>]*> 03e00008     jr      ra
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/branch-weak-2.d b/gas/testsuite/gas/mips/branch-weak-2.d
new file mode 100644 (file)
index 0000000..d97bace
--- /dev/null
@@ -0,0 +1,15 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS branch to a weak symbol
+#as: -32 -mmicromips --defsym align=12
+#source: branch-weak.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 9400 fffe    b       00000000 <foo>
+[      ]*[0-9a-f]+: R_MICROMIPS_PC16_S1        bar
+[0-9a-f]+ <[^>]*> 0c00         nop
+       \.\.\.
+[0-9a-f]+ <[^>]*> 459f         jr      ra
+[0-9a-f]+ <[^>]*> 0c00         nop
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/branch-weak-3.d b/gas/testsuite/gas/mips/branch-weak-3.d
new file mode 100644 (file)
index 0000000..93e06f5
--- /dev/null
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS relaxed branch to a weak symbol
+#as: -32 --relax-branch --defsym align=12
+#source: branch-weak.s
+#stderr: branch-weak.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 08000000     j       00000000 <foo>
+[      ]*[0-9a-f]+: R_MIPS_26  bar
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
+[0-9a-f]+ <[^>]*> 03e00008     jr      ra
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/branch-weak-4.d b/gas/testsuite/gas/mips/branch-weak-4.d
new file mode 100644 (file)
index 0000000..c8a2a4b
--- /dev/null
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS relaxed branch to a weak symbol
+#as: -32 -mmicromips --relax-branch --defsym align=12
+#source: branch-weak.s
+#stderr: branch-weak.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> d400 0000    j       00000000 <foo>
+[      ]*[0-9a-f]+: R_MICROMIPS_26_S1  bar
+[0-9a-f]+ <[^>]*> 0c00         nop
+       \.\.\.
+[0-9a-f]+ <[^>]*> 459f         jr      ra
+[0-9a-f]+ <[^>]*> 0c00         nop
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/branch-weak-5.d b/gas/testsuite/gas/mips/branch-weak-5.d
new file mode 100644 (file)
index 0000000..caeee97
--- /dev/null
@@ -0,0 +1,15 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS short branch to a weak symbol
+#as: -32 -mmicromips --defsym align=4
+#source: branch-weak.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 9400 fffe    b       00000000 <foo>
+[      ]*[0-9a-f]+: R_MICROMIPS_PC16_S1        bar
+[0-9a-f]+ <[^>]*> 0c00         nop
+       \.\.\.
+[0-9a-f]+ <[^>]*> 459f         jr      ra
+[0-9a-f]+ <[^>]*> 0c00         nop
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/branch-weak.l b/gas/testsuite/gas/mips/branch-weak.l
new file mode 100644 (file)
index 0000000..b0c248a
--- /dev/null
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:6: Warning: relaxed out-of-range branch into a jump
diff --git a/gas/testsuite/gas/mips/branch-weak.s b/gas/testsuite/gas/mips/branch-weak.s
new file mode 100644 (file)
index 0000000..eedef7a
--- /dev/null
@@ -0,0 +1,19 @@
+       .text
+       .align  4, 0
+       .globl  foo
+       .ent    foo
+foo:
+       b       bar
+       .end    foo
+
+       .align  align, 0
+       .globl  bar
+       .weak   bar
+       .ent    bar
+bar:
+       jr      $ra
+       .end    bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
index ad3cdfe..078fde2 100644 (file)
@@ -583,6 +583,11 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "branch-extern-2"
     run_dump_test "branch-extern-3"
     run_dump_test "branch-extern-4"
+    run_dump_test "branch-weak-1"
+    run_dump_test "branch-weak-2"
+    run_dump_test "branch-weak-3"
+    run_dump_test "branch-weak-4"
+    run_dump_test "branch-weak-5"
 
     run_dump_test "compact-eh-eb-1"
     run_dump_test "compact-eh-eb-2"