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 b5548b354a893466e67247521a5ee7db6c3be1a1..46605f9bee02e14f5af6ced15ad12d9a77bc71db 100644 (file)
@@ -1,3 +1,19 @@
+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
index dba147a98952609819657c04029bfb1410a4f217..118b91dfe61e090f2b3f982b982591d0e5ec705e 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 ad3cdfe80dae0b4e9b2b7c3638972493cb3d41f3..078fde263e6bbee08c3776c641165219f22d789f 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"