From 2a2b6d42b1a946cfaff8819925cdd15bee44d015 Mon Sep 17 00:00:00 2001 From: Doug Kwan Date: Mon, 22 Feb 2010 06:26:07 +0000 Subject: [PATCH] 2010-02-21 Doug Kwan * arm.cc (Arm_relocate_functions::arm_branch_common): Fix bug in handling of the maximum backward branch offset. (Arm_relocate_functions::thumb_branch_common): Ditto. * testsuite/Makefile.am (check_SCRIPTS): Add arm_branch_in_range.sh. (check_DATA): Add arm_bl_in_range.stdout, arm_bl_out_of_range.stdout thumb_bl_in_range.stdout, thumb_bl_out_of_range.stdout, thumb2_bl_in_range.stdout and thumb2_bl_out_of_range.stdout. (arm_bl_in_range.stdout, arm_bl_in_range, arm_bl_in_range.o, arm_bl_out_of_range.stdout, arm_bl_out_of_range, arm_bl_out_of_range.o, thumb_bl_in_range.stdout, thumb_bl_in_range, thumb_bl_in_range.o, thumb_bl_out_of_range.stdout, thumb_bl_out_of_range thumb_bl_out_of_range.o, thumb2_bl_in_range.stdout, thumb2_bl_in_range, thumb2_bl_in_range.o thumb2_bl_out_of_range.stdout, thumb2_bl_out_of_range, thumb2_bl_out_of_range.o): New rules. (MOSTLYCLEANFILES): Add arm_bl_in_range, arm_bl_out_of_range, thumb_bl_in_range, thumb_bl_out_of_range, thumb2_bl_in_range and thumb2_bl_out_of_range * testsuite/Makefile.in: Regenerate. * testsuite/arm_bl_in_range.s: New file. * testsuite/arm_bl_out_of_range.s: Ditto. * testsuite/arm_branch_in_range.sh: Ditto. * testsuite/arm_branch_range.t: Ditto. * testsuite/thumb2_branch_range.t: Ditto. * testsuite/thumb_bl_in_range.s: Ditto. * testsuite/thumb_bl_out_of_range.s: Ditto. * testsuite/thumb_branch_range.t: Ditto. --- gold/ChangeLog | 30 ++++++++++ gold/arm.cc | 25 +++++---- gold/testsuite/Makefile.am | 62 +++++++++++++++++++++ gold/testsuite/Makefile.in | 76 ++++++++++++++++++++++++-- gold/testsuite/arm_bl_in_range.s | 45 +++++++++++++++ gold/testsuite/arm_bl_out_of_range.s | 45 +++++++++++++++ gold/testsuite/arm_branch_in_range.sh | 57 +++++++++++++++++++ gold/testsuite/arm_branch_range.t | 36 ++++++++++++ gold/testsuite/thumb2_branch_range.t | 36 ++++++++++++ gold/testsuite/thumb_bl_in_range.s | 56 +++++++++++++++++++ gold/testsuite/thumb_bl_out_of_range.s | 56 +++++++++++++++++++ gold/testsuite/thumb_branch_range.t | 36 ++++++++++++ 12 files changed, 543 insertions(+), 17 deletions(-) create mode 100644 gold/testsuite/arm_bl_in_range.s create mode 100644 gold/testsuite/arm_bl_out_of_range.s create mode 100755 gold/testsuite/arm_branch_in_range.sh create mode 100644 gold/testsuite/arm_branch_range.t create mode 100644 gold/testsuite/thumb2_branch_range.t create mode 100644 gold/testsuite/thumb_bl_in_range.s create mode 100644 gold/testsuite/thumb_bl_out_of_range.s create mode 100644 gold/testsuite/thumb_branch_range.t diff --git a/gold/ChangeLog b/gold/ChangeLog index e752bf57a11..c9e60052530 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,33 @@ +2010-02-21 Doug Kwan + + * arm.cc (Arm_relocate_functions::arm_branch_common): Fix bug in + handling of the maximum backward branch offset. + (Arm_relocate_functions::thumb_branch_common): Ditto. + * testsuite/Makefile.am (check_SCRIPTS): Add arm_branch_in_range.sh. + (check_DATA): Add arm_bl_in_range.stdout, arm_bl_out_of_range.stdout + thumb_bl_in_range.stdout, thumb_bl_out_of_range.stdout, + thumb2_bl_in_range.stdout and thumb2_bl_out_of_range.stdout. + (arm_bl_in_range.stdout, arm_bl_in_range, arm_bl_in_range.o, + arm_bl_out_of_range.stdout, arm_bl_out_of_range, + arm_bl_out_of_range.o, thumb_bl_in_range.stdout, thumb_bl_in_range, + thumb_bl_in_range.o, thumb_bl_out_of_range.stdout, + thumb_bl_out_of_range thumb_bl_out_of_range.o, + thumb2_bl_in_range.stdout, thumb2_bl_in_range, thumb2_bl_in_range.o + thumb2_bl_out_of_range.stdout, thumb2_bl_out_of_range, + thumb2_bl_out_of_range.o): New rules. + (MOSTLYCLEANFILES): Add arm_bl_in_range, arm_bl_out_of_range, + thumb_bl_in_range, thumb_bl_out_of_range, thumb2_bl_in_range and + thumb2_bl_out_of_range + * testsuite/Makefile.in: Regenerate. + * testsuite/arm_bl_in_range.s: New file. + * testsuite/arm_bl_out_of_range.s: Ditto. + * testsuite/arm_branch_in_range.sh: Ditto. + * testsuite/arm_branch_range.t: Ditto. + * testsuite/thumb2_branch_range.t: Ditto. + * testsuite/thumb_bl_in_range.s: Ditto. + * testsuite/thumb_bl_out_of_range.s: Ditto. + * testsuite/thumb_branch_range.t: Ditto. + 2010-02-20 Sriraman Tallam * gc.h (gc_process_relocs): Change vectors to point to the new list. diff --git a/gold/arm.cc b/gold/arm.cc index 63484707b93..bc5557a7e44 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -3547,12 +3547,14 @@ Arm_relocate_functions::arm_branch_common( // to switch mode. bool may_use_blx = arm_target->may_use_blx(); Reloc_stub* stub = NULL; - if ((branch_offset > ARM_MAX_FWD_BRANCH_OFFSET) - || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET) + if (utils::has_overflow<26>(branch_offset) || ((thumb_bit != 0) && !(may_use_blx && r_type == elfcpp::R_ARM_CALL))) { + Valtype unadjusted_branch_target = psymval->value(object, 0); + Stub_type stub_type = - Reloc_stub::stub_type_for_reloc(r_type, address, branch_target, + Reloc_stub::stub_type_for_reloc(r_type, address, + unadjusted_branch_target, (thumb_bit != 0)); if (stub_type != arm_stub_none) { @@ -3566,8 +3568,7 @@ Arm_relocate_functions::arm_branch_common( thumb_bit = stub->stub_template()->entry_in_thumb_mode() ? 1 : 0; branch_target = stub_table->address() + stub->offset() + addend; branch_offset = branch_target - address; - gold_assert((branch_offset <= ARM_MAX_FWD_BRANCH_OFFSET) - && (branch_offset >= ARM_MAX_BWD_BRANCH_OFFSET)); + gold_assert(!utils::has_overflow<26>(branch_offset)); } } @@ -3675,19 +3676,19 @@ Arm_relocate_functions::thumb_branch_common( // to switch mode. bool may_use_blx = arm_target->may_use_blx(); bool thumb2 = arm_target->using_thumb2(); - if ((!thumb2 - && (branch_offset > THM_MAX_FWD_BRANCH_OFFSET - || (branch_offset < THM_MAX_BWD_BRANCH_OFFSET))) - || (thumb2 - && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET - || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET))) + if ((!thumb2 && utils::has_overflow<23>(branch_offset)) + || (thumb2 && utils::has_overflow<25>(branch_offset)) || ((thumb_bit == 0) && (((r_type == elfcpp::R_ARM_THM_CALL) && !may_use_blx) || r_type == elfcpp::R_ARM_THM_JUMP24))) { + Arm_address unadjusted_branch_target = psymval->value(object, 0); + Stub_type stub_type = - Reloc_stub::stub_type_for_reloc(r_type, address, branch_target, + Reloc_stub::stub_type_for_reloc(r_type, address, + unadjusted_branch_target, (thumb_bit != 0)); + if (stub_type != arm_stub_none) { Stub_table* stub_table = diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 3797a9219a2..eaf54467198 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -1467,4 +1467,66 @@ arm_abs_global.stdout: arm_abs_global MOSTLYCLEANFILES += arm_abs_global +check_SCRIPTS += arm_branch_in_range.sh +check_DATA += arm_bl_in_range.stdout arm_bl_out_of_range.stdout \ + thumb_bl_in_range.stdout thumb_bl_out_of_range.stdout \ + thumb2_bl_in_range.stdout thumb2_bl_out_of_range.stdout + +arm_bl_in_range.stdout: arm_bl_in_range + $(TEST_OBJDUMP) -D $< > $@ + +arm_bl_in_range: arm_bl_in_range.o + ../ld-new -T $(srcdir)/arm_branch_range.t -o $@ $< + +arm_bl_in_range.o: arm_bl_in_range.s + $(TEST_AS) -o $@ $< + +arm_bl_out_of_range.stdout: arm_bl_out_of_range + $(TEST_OBJDUMP) -S $< > $@ + +arm_bl_out_of_range: arm_bl_out_of_range.o + ../ld-new -T $(srcdir)/arm_branch_range.t -o $@ $< + +arm_bl_out_of_range.o: arm_bl_out_of_range.s + $(TEST_AS) -o $@ $< + +thumb_bl_in_range.stdout: thumb_bl_in_range + $(TEST_OBJDUMP) -D $< > $@ + +thumb_bl_in_range: thumb_bl_in_range.o + ../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $< + +thumb_bl_in_range.o: thumb_bl_in_range.s + $(TEST_AS) -o $@ -march=armv5te $< + +thumb_bl_out_of_range.stdout: thumb_bl_out_of_range + $(TEST_OBJDUMP) -D $< > $@ + +thumb_bl_out_of_range: thumb_bl_in_range.o + ../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $< + +thumb_bl_out_of_range.o: thumb_bl_in_range.s + $(TEST_AS) -o $@ -march=armv5te $< + +thumb2_bl_in_range.stdout: thumb2_bl_in_range + $(TEST_OBJDUMP) -D $< > $@ + +thumb2_bl_in_range: thumb2_bl_in_range.o + ../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $< + +thumb2_bl_in_range.o: thumb_bl_in_range.s + $(TEST_AS) -o $@ -march=armv7-a $< + +thumb2_bl_out_of_range.stdout: thumb2_bl_out_of_range + $(TEST_OBJDUMP) -D $< > $@ + +thumb2_bl_out_of_range: thumb2_bl_in_range.o + ../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $< + +thumb2_bl_out_of_range.o: thumb_bl_in_range.s + $(TEST_AS) -o $@ -march=armv7-a $< + +MOSTLYCLEANFILES += arm_bl_in_range arm_bl_out_of_range thumb_bl_in_range \ + thumb_bl_out_of_range thumb2_bl_in_range thumb2_bl_out_of_range + endif DEFAULT_TARGET_ARM diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index e3c356a7afb..bbffd69c86d 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -322,9 +322,21 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @DEFAULT_TARGET_X86_64_TRUE@am__append_37 = split_x86_64_1 split_x86_64_2 split_x86_64_3 \ @DEFAULT_TARGET_X86_64_TRUE@ split_x86_64_4 split_x86_64_r -@DEFAULT_TARGET_ARM_TRUE@am__append_38 = arm_abs_global.sh -@DEFAULT_TARGET_ARM_TRUE@am__append_39 = arm_abs_global.stdout -@DEFAULT_TARGET_ARM_TRUE@am__append_40 = arm_abs_global +@DEFAULT_TARGET_ARM_TRUE@am__append_38 = arm_abs_global.sh \ +@DEFAULT_TARGET_ARM_TRUE@ arm_branch_in_range.sh +@DEFAULT_TARGET_ARM_TRUE@am__append_39 = arm_abs_global.stdout \ +@DEFAULT_TARGET_ARM_TRUE@ arm_bl_in_range.stdout \ +@DEFAULT_TARGET_ARM_TRUE@ arm_bl_out_of_range.stdout \ +@DEFAULT_TARGET_ARM_TRUE@ thumb_bl_in_range.stdout \ +@DEFAULT_TARGET_ARM_TRUE@ thumb_bl_out_of_range.stdout \ +@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_in_range.stdout \ +@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_out_of_range.stdout +@DEFAULT_TARGET_ARM_TRUE@am__append_40 = arm_abs_global \ +@DEFAULT_TARGET_ARM_TRUE@ arm_bl_in_range arm_bl_out_of_range \ +@DEFAULT_TARGET_ARM_TRUE@ thumb_bl_in_range \ +@DEFAULT_TARGET_ARM_TRUE@ thumb_bl_out_of_range \ +@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_in_range \ +@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_out_of_range subdir = testsuite DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -2648,7 +2660,7 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--icf=all -Wl,--keep-unique,_Z11unique_funcv icf_keep_unique_test.o @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_keep_unique_test.stdout: icf_keep_unique_test @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -C icf_keep_unique_test > icf_keep_unique_test.stdout -@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_test.o: icf_safe_test.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_test.o: icf_safe_test.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $< @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_test: icf_safe_test.o gcctestdir/ld @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--icf=safe icf_safe_test.o @@ -2656,7 +2668,7 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) icf_safe_test > icf_safe_test_1.stdout @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_test_2.stdout: icf_safe_test @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -h icf_safe_test > icf_safe_test_2.stdout -@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_so_test.o: icf_safe_so_test.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_so_test.o: icf_safe_so_test.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -fPIC -g -o $@ $< @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_so_test: icf_safe_so_test.o gcctestdir/ld @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--icf=safe icf_safe_so_test.o -fPIC -shared @@ -3222,6 +3234,60 @@ uninstall-am: @DEFAULT_TARGET_ARM_TRUE@arm_abs_global.stdout: arm_abs_global @DEFAULT_TARGET_ARM_TRUE@ $(TEST_READELF) -r $< > $@ +@DEFAULT_TARGET_ARM_TRUE@arm_bl_in_range.stdout: arm_bl_in_range +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@ + +@DEFAULT_TARGET_ARM_TRUE@arm_bl_in_range: arm_bl_in_range.o +@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/arm_branch_range.t -o $@ $< + +@DEFAULT_TARGET_ARM_TRUE@arm_bl_in_range.o: arm_bl_in_range.s +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ $< + +@DEFAULT_TARGET_ARM_TRUE@arm_bl_out_of_range.stdout: arm_bl_out_of_range +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -S $< > $@ + +@DEFAULT_TARGET_ARM_TRUE@arm_bl_out_of_range: arm_bl_out_of_range.o +@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/arm_branch_range.t -o $@ $< + +@DEFAULT_TARGET_ARM_TRUE@arm_bl_out_of_range.o: arm_bl_out_of_range.s +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ $< + +@DEFAULT_TARGET_ARM_TRUE@thumb_bl_in_range.stdout: thumb_bl_in_range +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@ + +@DEFAULT_TARGET_ARM_TRUE@thumb_bl_in_range: thumb_bl_in_range.o +@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $< + +@DEFAULT_TARGET_ARM_TRUE@thumb_bl_in_range.o: thumb_bl_in_range.s +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv5te $< + +@DEFAULT_TARGET_ARM_TRUE@thumb_bl_out_of_range.stdout: thumb_bl_out_of_range +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@ + +@DEFAULT_TARGET_ARM_TRUE@thumb_bl_out_of_range: thumb_bl_in_range.o +@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $< + +@DEFAULT_TARGET_ARM_TRUE@thumb_bl_out_of_range.o: thumb_bl_in_range.s +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv5te $< + +@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_in_range.stdout: thumb2_bl_in_range +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@ + +@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_in_range: thumb2_bl_in_range.o +@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $< + +@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_in_range.o: thumb_bl_in_range.s +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv7-a $< + +@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_out_of_range.stdout: thumb2_bl_out_of_range +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@ + +@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_out_of_range: thumb2_bl_in_range.o +@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $< + +@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_out_of_range.o: thumb_bl_in_range.s +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv7-a $< + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/gold/testsuite/arm_bl_in_range.s b/gold/testsuite/arm_bl_in_range.s new file mode 100644 index 00000000000..23960f9ab90 --- /dev/null +++ b/gold/testsuite/arm_bl_in_range.s @@ -0,0 +1,45 @@ +# arm_bl_in_range.s +# Test ARM bl instructions just within branch range limits. + .syntax unified + .arch armv5te + + .section .text.pre,"x" + +# Add padding so that target is just within branch range. + .space 12 + + .align 2 + .global _backward_target +_backward_target: + bx lr + .size _backward_target, .-_backward_target + + .text + .align 2 + +# Define _start so that linker does not complain. + .global _start +_start: + bx lr + .size _start, .-_start + + .global _backward_test +_backward_test: + bl _backward_target + .size _backward_test, .-_backward_test + + .global _forward_test +_forward_test: + bl _forward_target + .size _forward_test, .-_forward_test + + .section .text.post,"x" + +# Add padding so that target is just within of branch range. + .space 12 + + .align 2 + .global _forward_target +_forward_target: + bx lr + .size _forward_target, .-_forward_target diff --git a/gold/testsuite/arm_bl_out_of_range.s b/gold/testsuite/arm_bl_out_of_range.s new file mode 100644 index 00000000000..786d9aabf92 --- /dev/null +++ b/gold/testsuite/arm_bl_out_of_range.s @@ -0,0 +1,45 @@ +# arm_bl_out_of_range.s +# Test ARM bl instructions just out of the branch range limits. + .syntax unified + .arch armv5te + + .section .text.pre,"x" + +# Add padding so that target is just out of branch range. + .space 8 + + .align 2 + .global _backward_target +_backward_target: + bx lr + .size _backward_target, .-_backward_target + + .text + .align 2 + +# Define _start so that linker does not complain. + .global _start +_start: + bx lr + .size _start, .-_start + + .global _backward_test +_backward_test: + bl _backward_target + .size _backward_test, .-_backward_test + + .global _forward_test +_forward_test: + bl _forward_target + .size _forward_test, .-_forward_test + + .section .text.post,"x" + +# Add padding so that target is just out of branch range. + .space 16 + + .align 2 + .global _forward_target +_forward_target: + bx lr + .size _forward_target, .-_forward_target diff --git a/gold/testsuite/arm_branch_in_range.sh b/gold/testsuite/arm_branch_in_range.sh new file mode 100755 index 00000000000..b676770013f --- /dev/null +++ b/gold/testsuite/arm_branch_in_range.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# arm_branch_in_range.sh -- test ARM/THUMB/THUMB branch instructions whose +# targets are just within the branch range limits. + +# Copyright 2010 Free Software Foundation, Inc. +# Written by Doug Kwan + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# This file goes with the assembler source files arm_bl_in_range.s +# thumb_bl_in_range.s that are assembled and linked to check that branches +# whose target are just within the branch range limits are handle correctly. + +check() +{ + file=$1 + pattern=$2 + + found=`grep "$pattern" $file` + if test -z "$found"; then + echo "pattern \"$pattern\" not found in file $file." + exit 1 + fi +} + +# This is a bit crude. Also, there are tabs in the grep patterns. + +check arm_bl_in_range.stdout \ + " 4000004: eb800000 bl 200000c <_backward_target>" +check arm_bl_in_range.stdout \ + " 4000008: eb7fffff bl 600000c <_forward_target>" +check thumb_bl_in_range.stdout \ + " 800004: f400 f800 bl 400008 <_backward_target>" +check thumb_bl_in_range.stdout \ + " 800008: f3ff ffff bl c0000a <_forward_target>" +check thumb2_bl_in_range.stdout \ + " 2000004: f400 d000 bl 1000008 <_backward_target>" +check thumb2_bl_in_range.stdout \ + " 2000008: f3ff d7ff bl 300000a <_forward_target>" + +exit 0 diff --git a/gold/testsuite/arm_branch_range.t b/gold/testsuite/arm_branch_range.t new file mode 100644 index 00000000000..865e40424eb --- /dev/null +++ b/gold/testsuite/arm_branch_range.t @@ -0,0 +1,36 @@ +/* arm_banch_range.t -- linker script to test ARM branch range. + + Copyright 2010 Free Software Foundation, Inc. + Written by Doug Kwan . + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +SECTIONS +{ + . = 0x2000000; + + .text.pre : { *(.text.pre) } + . = ALIGN(0x2000000); + .text : { *(.text) } + . = ALIGN(0x2000000); + .text.post : { *(.text.post) } + . += 0x1000; + .data : { *(.data) } + .bss : { *(.bss) } + .ARM.attributes : { *(.ARM.attributes) } +} diff --git a/gold/testsuite/thumb2_branch_range.t b/gold/testsuite/thumb2_branch_range.t new file mode 100644 index 00000000000..8fdc783664e --- /dev/null +++ b/gold/testsuite/thumb2_branch_range.t @@ -0,0 +1,36 @@ +/* thumb2_banch_range.t -- linker script to test THUMB-2 branch range. + + Copyright 2010 Free Software Foundation, Inc. + Written by Doug Kwan . + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +SECTIONS +{ + . = 0x1000000; + + .text.pre : { *(.text.pre) } + . = ALIGN(0x1000000); + .text : { *(.text) } + . = ALIGN(0x1000000); + .text.post : { *(.text.post) } + . += 0x1000; + .data : { *(.data) } + .bss : { *(.bss) } + .ARM.attributes : { *(.ARM.attributes) } +} diff --git a/gold/testsuite/thumb_bl_in_range.s b/gold/testsuite/thumb_bl_in_range.s new file mode 100644 index 00000000000..4a40ae2089c --- /dev/null +++ b/gold/testsuite/thumb_bl_in_range.s @@ -0,0 +1,56 @@ +# thumb_bl_in_range.s +# Test THUMB/THUMB-2 bl instructions just within the branch range limits. + .syntax unified + + .section .text.pre,"x" + +# Add padding so that target is just in branch range. + .space 8 + + .global _backward_target + .code 16 + .thumb_func + .type _backword_target, %function +_backward_target: + bx lr + .size _backward_target, .-_backward_target + + .text + +# Define _start so that linker does not complain. + .global _start + .code 32 + .align 2 + .type _start, %function +_start: + bx lr + .size _start, .-_start + + .global _backward_test + .code 16 + .thumb_func + .type _backward_test, %function +_backward_test: + bl _backward_target + .size _backward_test, .-_backward_test + + .global _forward_test + .code 16 + .thumb_func + .type _forward_test, %function +_forward_test: + bl _forward_target + .size _forward_test, .-_forward_test + + .section .text.post,"x" + +# Add padding so that target is just in branch range. + .space 10 + + .global _forward_target + .code 16 + .thumb_func + .type _forward_target, %function +_forward_target: + bx lr + .size _forward_target, .-_forward_target diff --git a/gold/testsuite/thumb_bl_out_of_range.s b/gold/testsuite/thumb_bl_out_of_range.s new file mode 100644 index 00000000000..6629d74af0a --- /dev/null +++ b/gold/testsuite/thumb_bl_out_of_range.s @@ -0,0 +1,56 @@ +# thumb_bl_out_of_range.s +# Test THUMB/THUMB-2 bl instructions just out of the branch range limits. + .syntax unified + + .section .text.pre,"x" + +# Add padding so that target is just output of branch range. + .space 6 + + .global _backward_target + .code 16 + .thumb_func + .type _backword_target, %function +_backward_target: + bx lr + .size _backward_target, .-_backward_target + + .text + +# Define _start so that linker does not complain. + .global _start + .code 32 + .align 2 + .type _start, %function +_start: + bx lr + .size _start, .-_start + + .global _backward_test + .code 16 + .thumb_func + .type _backward_test, %function +_backward_test: + bl _backward_target + .size _backward_test, .-_backward_test + + .global _forward_test + .code 16 + .thumb_func + .type _forward_test, %function +_forward_test: + bl _forward_target + .size _forward_test, .-_forward_test + + .section .text.post,"x" + +# Add padding so that target is just out of branch range. + .space 12 + + .global _forward_target + .code 16 + .thumb_func + .type _forward_target, %function +_forward_target: + bx lr + .size _forward_target, .-_forward_target diff --git a/gold/testsuite/thumb_branch_range.t b/gold/testsuite/thumb_branch_range.t new file mode 100644 index 00000000000..fa858b55479 --- /dev/null +++ b/gold/testsuite/thumb_branch_range.t @@ -0,0 +1,36 @@ +/* thumb_banch_range.t -- linker script to test ARM branch range. + + Copyright 2010 Free Software Foundation, Inc. + Written by Doug Kwan . + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +SECTIONS +{ + . = 0x400000; + + .text.pre : { *(.text.pre) } + . = ALIGN(0x400000); + .text : { *(.text) } + . = ALIGN(0x400000); + .text.post : { *(.text.post) } + . += 0x1000; + .data : { *(.data) } + .bss : { *(.bss) } + .ARM.attributes : { *(.ARM.attributes) } +} -- 2.30.2