2010-02-21 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Mon, 22 Feb 2010 06:26:07 +0000 (06:26 +0000)
committerDoug Kwan <dougkwan@google.com>
Mon, 22 Feb 2010 06:26:07 +0000 (06:26 +0000)
* 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.

12 files changed:
gold/ChangeLog
gold/arm.cc
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/arm_bl_in_range.s [new file with mode: 0644]
gold/testsuite/arm_bl_out_of_range.s [new file with mode: 0644]
gold/testsuite/arm_branch_in_range.sh [new file with mode: 0755]
gold/testsuite/arm_branch_range.t [new file with mode: 0644]
gold/testsuite/thumb2_branch_range.t [new file with mode: 0644]
gold/testsuite/thumb_bl_in_range.s [new file with mode: 0644]
gold/testsuite/thumb_bl_out_of_range.s [new file with mode: 0644]
gold/testsuite/thumb_branch_range.t [new file with mode: 0644]

index e752bf5..c9e6005 100644 (file)
@@ -1,3 +1,33 @@
+2010-02-21  Doug Kwan  <dougkwan@google.com>
+
+       * 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  <tmsriram@google.com>
 
        * gc.h (gc_process_relocs): Change vectors to point to the new list.
index 6348470..bc5557a 100644 (file)
@@ -3547,12 +3547,14 @@ Arm_relocate_functions<big_endian>::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<big_endian>::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<big_endian>::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<big_endian>* stub_table =
index 3797a92..eaf5446 100644 (file)
@@ -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
index e3c356a..bbffd69 100644 (file)
@@ -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 (file)
index 0000000..23960f9
--- /dev/null
@@ -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 (file)
index 0000000..786d9aa
--- /dev/null
@@ -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 (executable)
index 0000000..b676770
--- /dev/null
@@ -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 <dougkwan@google.com>
+
+# 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 (file)
index 0000000..865e404
--- /dev/null
@@ -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 <dougkwan@google.com>.
+
+   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 (file)
index 0000000..8fdc783
--- /dev/null
@@ -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 <dougkwan@google.com>.
+
+   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 (file)
index 0000000..4a40ae2
--- /dev/null
@@ -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 (file)
index 0000000..6629d74
--- /dev/null
@@ -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 (file)
index 0000000..fa858b5
--- /dev/null
@@ -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 <dougkwan@google.com>.
+
+   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) }
+}