[PATCH][GOLD] Fix handling of maximum branch offsets.

Doug Kwan (關振德) dougkwan@google.com
Mon Feb 22 04:32:00 GMT 2010


Hi,

    This patch fixes a bug in handling of maximum branch offsets that
caused the linker to crash last week.  The bug was discovered when we
tested gold with a very big binary that happened to contain a THUMB2
long branch with the maximum backward branch offset.  The same problem
also happened in ARM and THUMB long branches.  I also added some
regression tests.

-Doug

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.
-------------- next part --------------
Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.83
diff -u -u -p -r1.83 arm.cc
--- gold/arm.cc	19 Feb 2010 22:53:54 -0000	1.83
+++ gold/arm.cc	22 Feb 2010 02:32:45 -0000
@@ -3547,12 +3547,14 @@ Arm_relocate_functions<big_endian>::arm_
   // 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_
 	  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>::thum
   // 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: gold/testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.122
diff -u -u -p -r1.122 Makefile.am
--- gold/testsuite/Makefile.am	13 Feb 2010 02:04:21 -0000	1.122
+++ gold/testsuite/Makefile.am	22 Feb 2010 02:32:45 -0000
@@ -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: gold/testsuite/Makefile.in
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.in,v
retrieving revision 1.128
diff -u -u -p -r1.128 Makefile.in
--- gold/testsuite/Makefile.in	13 Feb 2010 02:04:21 -0000	1.128
+++ gold/testsuite/Makefile.in	22 Feb 2010 02:32:45 -0000
@@ -322,9 +322,21 @@ check_PROGRAMS = object_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:
Index: gold/testsuite/arm_bl_in_range.s
===================================================================
RCS file: gold/testsuite/arm_bl_in_range.s
diff -N gold/testsuite/arm_bl_in_range.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_bl_in_range.s	22 Feb 2010 02:32:45 -0000
@@ -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
Index: gold/testsuite/arm_bl_out_of_range.s
===================================================================
RCS file: gold/testsuite/arm_bl_out_of_range.s
diff -N gold/testsuite/arm_bl_out_of_range.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_bl_out_of_range.s	22 Feb 2010 02:32:45 -0000
@@ -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
Index: gold/testsuite/arm_branch_in_range.sh
===================================================================
RCS file: gold/testsuite/arm_branch_in_range.sh
diff -N gold/testsuite/arm_branch_in_range.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_branch_in_range.sh	22 Feb 2010 02:32:45 -0000
@@ -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
Index: gold/testsuite/arm_branch_range.t
===================================================================
RCS file: gold/testsuite/arm_branch_range.t
diff -N gold/testsuite/arm_branch_range.t
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_branch_range.t	22 Feb 2010 02:32:45 -0000
@@ -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) }
+}
Index: gold/testsuite/thumb2_branch_range.t
===================================================================
RCS file: gold/testsuite/thumb2_branch_range.t
diff -N gold/testsuite/thumb2_branch_range.t
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/thumb2_branch_range.t	22 Feb 2010 02:32:45 -0000
@@ -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) }
+}
Index: gold/testsuite/thumb_bl_in_range.s
===================================================================
RCS file: gold/testsuite/thumb_bl_in_range.s
diff -N gold/testsuite/thumb_bl_in_range.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/thumb_bl_in_range.s	22 Feb 2010 02:32:45 -0000
@@ -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
Index: gold/testsuite/thumb_bl_out_of_range.s
===================================================================
RCS file: gold/testsuite/thumb_bl_out_of_range.s
diff -N gold/testsuite/thumb_bl_out_of_range.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/thumb_bl_out_of_range.s	22 Feb 2010 02:32:45 -0000
@@ -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
Index: gold/testsuite/thumb_branch_range.t
===================================================================
RCS file: gold/testsuite/thumb_branch_range.t
diff -N gold/testsuite/thumb_branch_range.t
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/thumb_branch_range.t	22 Feb 2010 02:32:45 -0000
@@ -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) }
+}


More information about the Binutils mailing list