aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2010-02-22 06:26:07 +0000
committerDoug Kwan <dougkwan@google.com>2010-02-22 06:26:07 +0000
commit2a2b6d42b1a946cfaff8819925cdd15bee44d015 (patch)
treec434f4f73a93b26045882f05cb1b75f5e468f578
parent109af718c00cca36ea5c141464bfb51fbac068ce (diff)
downloadgdb-2a2b6d42b1a946cfaff8819925cdd15bee44d015.zip
gdb-2a2b6d42b1a946cfaff8819925cdd15bee44d015.tar.gz
gdb-2a2b6d42b1a946cfaff8819925cdd15bee44d015.tar.bz2
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.
-rw-r--r--gold/ChangeLog30
-rw-r--r--gold/arm.cc25
-rw-r--r--gold/testsuite/Makefile.am62
-rw-r--r--gold/testsuite/Makefile.in76
-rw-r--r--gold/testsuite/arm_bl_in_range.s45
-rw-r--r--gold/testsuite/arm_bl_out_of_range.s45
-rwxr-xr-xgold/testsuite/arm_branch_in_range.sh57
-rw-r--r--gold/testsuite/arm_branch_range.t36
-rw-r--r--gold/testsuite/thumb2_branch_range.t36
-rw-r--r--gold/testsuite/thumb_bl_in_range.s56
-rw-r--r--gold/testsuite/thumb_bl_out_of_range.s56
-rw-r--r--gold/testsuite/thumb_branch_range.t36
12 files changed, 543 insertions, 17 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index e752bf5..c9e6005 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -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.
diff --git a/gold/arm.cc b/gold/arm.cc
index 6348470..bc5557a 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -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 =
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index 3797a92..eaf5446 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 e3c356a..bbffd69 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 0000000..23960f9
--- /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 0000000..786d9aa
--- /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 0000000..b676770
--- /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 <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
index 0000000..865e404
--- /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 <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
index 0000000..8fdc783
--- /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 <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
index 0000000..4a40ae2
--- /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 0000000..6629d74
--- /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 0000000..fa858b5
--- /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 <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) }
+}