From 991f40a9fa668eb65159ee9884bf89c8cbc09f02 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 9 Apr 2016 11:59:36 +0100 Subject: [PATCH] MIPS/GAS: Correct branch relaxation for weak symbols 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 Andrew Bennett 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 | 16 ++++++++++++++++ gas/config/tc-mips.c | 3 +++ gas/testsuite/gas/mips/branch-weak-1.d | 15 +++++++++++++++ gas/testsuite/gas/mips/branch-weak-2.d | 15 +++++++++++++++ gas/testsuite/gas/mips/branch-weak-3.d | 16 ++++++++++++++++ gas/testsuite/gas/mips/branch-weak-4.d | 16 ++++++++++++++++ gas/testsuite/gas/mips/branch-weak-5.d | 15 +++++++++++++++ gas/testsuite/gas/mips/branch-weak.l | 2 ++ gas/testsuite/gas/mips/branch-weak.s | 19 +++++++++++++++++++ gas/testsuite/gas/mips/mips.exp | 5 +++++ 10 files changed, 122 insertions(+) create mode 100644 gas/testsuite/gas/mips/branch-weak-1.d create mode 100644 gas/testsuite/gas/mips/branch-weak-2.d create mode 100644 gas/testsuite/gas/mips/branch-weak-3.d create mode 100644 gas/testsuite/gas/mips/branch-weak-4.d create mode 100644 gas/testsuite/gas/mips/branch-weak-5.d create mode 100644 gas/testsuite/gas/mips/branch-weak.l create mode 100644 gas/testsuite/gas/mips/branch-weak.s diff --git a/gas/ChangeLog b/gas/ChangeLog index b5548b354a..46605f9bee 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,19 @@ +2016-04-13 Maciej W. Rozycki + Andrew Bennett + + * 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 * config/tc-mips.c (relaxed_branch_length): Use the long diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index dba147a989..118b91dfe6 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -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 index 0000000000..859a2ca69f --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak-1.d @@ -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 +[ ]*[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 index 0000000000..d97bace235 --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak-2.d @@ -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 +[ ]*[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 index 0000000000..93e06f5940 --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak-3.d @@ -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 +[ ]*[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 index 0000000000..c8a2a4b907 --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak-4.d @@ -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 +[ ]*[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 index 0000000000..caeee975a5 --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak-5.d @@ -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 +[ ]*[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 index 0000000000..b0c248adde --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak.l @@ -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 index 0000000000..eedef7a547 --- /dev/null +++ b/gas/testsuite/gas/mips/branch-weak.s @@ -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 diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index ad3cdfe80d..078fde263e 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -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"