2010-02-26 Doug Kwan <dougkwan@google.com>

* arm.cc (Target_arm::scan_reloc_for_stub): Move code handling
	R_ARM_V4BX to Target_arm::scan_reloc_section_for_stubs.
	(Target_arm::scan_reloc_section_for_stubs): Instead of calling
	scan_reloc_for_stub, do all processing of R_ARM_V4BX here.
	* options.cc (General_options::General_options): Initialize member
	fix_v4bx_.
	* testsuite/Makefile.am (check_SCRIPTS): Add arm_fix_v4bx.sh
	(check_DATA): Add arm_fix_v4bx.stdout, arm_fix_v4bx_interworking.stdout
	and rm_no_fix_v4bx.stdout
	(arm_fix_v4bx.stdout, arm_fix_v4bx, arm_fix_v4bx.o,
	arm_fix_v4bx_interworking.stdout, arm_fix_v4bx_interworking,
	arm_no_fix_v4bx.stdout, arm_no_fix_v4bx): New make rules.
	(MOSTLYCLEANFILES): Add arm_fix_v4bx, arm_fix_v4bx_interworking
	and arm_no_fix_v4bx.
	* Makefile.in: Regenerate.
	* testsuite/arm_fix_v4bx.s: New file.
	* testsuite/arm_fix_v4bx.sh: Ditto.
This commit is contained in:
Doug Kwan 2010-02-27 00:36:49 +00:00
parent 505c014f55
commit 2fd9ae7a1d
7 changed files with 178 additions and 35 deletions

View File

@ -1,3 +1,23 @@
2010-02-26 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::scan_reloc_for_stub): Move code handling
R_ARM_V4BX to Target_arm::scan_reloc_section_for_stubs.
(Target_arm::scan_reloc_section_for_stubs): Instead of calling
scan_reloc_for_stub, do all processing of R_ARM_V4BX here.
* options.cc (General_options::General_options): Initialize member
fix_v4bx_.
* testsuite/Makefile.am (check_SCRIPTS): Add arm_fix_v4bx.sh
(check_DATA): Add arm_fix_v4bx.stdout, arm_fix_v4bx_interworking.stdout
and rm_no_fix_v4bx.stdout
(arm_fix_v4bx.stdout, arm_fix_v4bx, arm_fix_v4bx.o,
arm_fix_v4bx_interworking.stdout, arm_fix_v4bx_interworking,
arm_no_fix_v4bx.stdout, arm_no_fix_v4bx): New make rules.
(MOSTLYCLEANFILES): Add arm_fix_v4bx, arm_fix_v4bx_interworking
and arm_no_fix_v4bx.
* Makefile.in: Regenerate.
* testsuite/arm_fix_v4bx.s: New file.
* testsuite/arm_fix_v4bx.sh: Ditto.
2010-02-24 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::got_section): Make the .got section the first

View File

@ -9880,30 +9880,6 @@ Target_arm<big_endian>::scan_reloc_for_stub(
const Arm_relobj<big_endian>* arm_relobj =
Arm_relobj<big_endian>::as_arm_relobj(relinfo->object);
if (r_type == elfcpp::R_ARM_V4BX)
{
const uint32_t reg = (addend & 0xf);
if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING
&& reg < 0xf)
{
// Try looking up an existing stub from a stub table.
Stub_table<big_endian>* stub_table =
arm_relobj->stub_table(relinfo->data_shndx);
gold_assert(stub_table != NULL);
if (stub_table->find_arm_v4bx_stub(reg) == NULL)
{
// create a new stub and add it to stub table.
Arm_v4bx_stub* stub =
this->stub_factory().make_arm_v4bx_stub(reg);
gold_assert(stub != NULL);
stub_table->add_arm_v4bx_stub(stub);
}
}
return;
}
bool target_is_thumb;
Symbol_value<32> symval;
if (gsym != NULL)
@ -10094,15 +10070,36 @@ Target_arm<big_endian>::scan_reloc_section_for_stubs(
continue;
}
// Create a v4bx stub if --fix-v4bx-interworking is used.
if (r_type == elfcpp::R_ARM_V4BX)
{
// Get the BX instruction.
typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
const Valtype* wv = reinterpret_cast<const Valtype*>(view + offset);
elfcpp::Elf_types<32>::Elf_Swxword insn =
elfcpp::Swap<32, big_endian>::readval(wv);
this->scan_reloc_for_stub(relinfo, r_type, NULL, 0, NULL,
insn, NULL);
if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING)
{
// Get the BX instruction.
typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
const Valtype* wv =
reinterpret_cast<const Valtype*>(view + offset);
elfcpp::Elf_types<32>::Elf_Swxword insn =
elfcpp::Swap<32, big_endian>::readval(wv);
const uint32_t reg = (insn & 0xf);
if (reg < 0xf)
{
// Try looking up an existing stub from a stub table.
Stub_table<big_endian>* stub_table =
arm_object->stub_table(relinfo->data_shndx);
gold_assert(stub_table != NULL);
if (stub_table->find_arm_v4bx_stub(reg) == NULL)
{
// create a new stub and add it to stub table.
Arm_v4bx_stub* stub =
this->stub_factory().make_arm_v4bx_stub(reg);
gold_assert(stub != NULL);
stub_table->add_arm_v4bx_stub(stub);
}
}
}
continue;
}

View File

@ -830,7 +830,8 @@ General_options::General_options()
implicit_incremental_(false),
excluded_libs_(),
symbols_to_retain_(),
section_starts_()
section_starts_(),
fix_v4bx_(FIX_V4BX_NONE)
{
// Turn off option registration once construction is complete.
gold::options::ready_to_register = false;

View File

@ -1529,4 +1529,31 @@ thumb2_bl_out_of_range.o: thumb_bl_in_range.s
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
check_SCRIPTS += arm_fix_v4bx.sh
check_DATA += arm_fix_v4bx.stdout arm_fix_v4bx_interworking.stdout \
arm_no_fix_v4bx.stdout
arm_fix_v4bx.stdout: arm_fix_v4bx
$(TEST_OBJDUMP) -D -j.text $< > $@
arm_fix_v4bx: arm_fix_v4bx.o
../ld-new --fix-v4bx -o $@ $<
arm_fix_v4bx.o: arm_fix_v4bx.s
$(TEST_AS) -o $@ $<
arm_fix_v4bx_interworking.stdout: arm_fix_v4bx_interworking
$(TEST_OBJDUMP) -D -j.text $< > $@
arm_fix_v4bx_interworking: arm_fix_v4bx.o
../ld-new --fix-v4bx-interworking -o $@ $<
arm_no_fix_v4bx.stdout: arm_no_fix_v4bx
$(TEST_OBJDUMP) -D -j.text $< > $@
arm_no_fix_v4bx: arm_fix_v4bx.o
../ld-new -o $@ $<
MOSTLYCLEANFILES += arm_fix_v4bx arm_fix_v4bx_interworking arm_no_fix_v4bx
endif DEFAULT_TARGET_ARM

View File

@ -323,20 +323,26 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
@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@ arm_branch_in_range.sh
@DEFAULT_TARGET_ARM_TRUE@ arm_branch_in_range.sh \
@DEFAULT_TARGET_ARM_TRUE@ arm_fix_v4bx.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@ thumb2_bl_out_of_range.stdout \
@DEFAULT_TARGET_ARM_TRUE@ arm_fix_v4bx.stdout \
@DEFAULT_TARGET_ARM_TRUE@ arm_fix_v4bx_interworking.stdout \
@DEFAULT_TARGET_ARM_TRUE@ arm_no_fix_v4bx.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
@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_out_of_range arm_fix_v4bx \
@DEFAULT_TARGET_ARM_TRUE@ arm_fix_v4bx_interworking \
@DEFAULT_TARGET_ARM_TRUE@ arm_no_fix_v4bx
subdir = testsuite
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@ -3288,6 +3294,27 @@ uninstall-am:
@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 $<
@DEFAULT_TARGET_ARM_TRUE@arm_fix_v4bx.stdout: arm_fix_v4bx
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D -j.text $< > $@
@DEFAULT_TARGET_ARM_TRUE@arm_fix_v4bx: arm_fix_v4bx.o
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new --fix-v4bx -o $@ $<
@DEFAULT_TARGET_ARM_TRUE@arm_fix_v4bx.o: arm_fix_v4bx.s
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ $<
@DEFAULT_TARGET_ARM_TRUE@arm_fix_v4bx_interworking.stdout: arm_fix_v4bx_interworking
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D -j.text $< > $@
@DEFAULT_TARGET_ARM_TRUE@arm_fix_v4bx_interworking: arm_fix_v4bx.o
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new --fix-v4bx-interworking -o $@ $<
@DEFAULT_TARGET_ARM_TRUE@arm_no_fix_v4bx.stdout: arm_no_fix_v4bx
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D -j.text $< > $@
@DEFAULT_TARGET_ARM_TRUE@arm_no_fix_v4bx: arm_fix_v4bx.o
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -o $@ $<
# 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:

View File

@ -0,0 +1,15 @@
.syntax unified
.text
# Align this to 256-byte boundary for easier address matching.
.align 8
# We do not want to run this file. We define _start here to avoid missing
# entry point.
.global _start
.type _start, %function
_start:
bx r0
bx r15
.size _start, .-_start

56
gold/testsuite/arm_fix_v4bx.sh Executable file
View File

@ -0,0 +1,56 @@
#!/bin/sh
# arm_v4bx.sh -- a test case for --fix-v4bx and --fix-v4bx-interworking.
# 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 arm_v4bx.s, an ARM assembly source file constructed to
# have test the handling of R_ARM_V4BX relocation.
check()
{
if ! grep -q "$2" "$1"
then
echo "Did not find expected instruction in $1:"
echo " $2"
echo ""
echo "Actual instructions below:"
cat "$1"
exit 1
fi
}
# Test --fix-v4bx
check arm_fix_v4bx.stdout ".*00: .* mov pc, r0"
check arm_fix_v4bx.stdout ".*04: .* mov pc, pc"
# Test --fix-v4bx-interworking
check arm_fix_v4bx_interworking.stdout ".*00: .* b .*00 <.*>"
check arm_fix_v4bx_interworking.stdout ".*04: .* mov pc, pc"
check arm_fix_v4bx_interworking.stdout ".*00: .* tst r0, #1"
check arm_fix_v4bx_interworking.stdout ".*04: .* moveq pc, r0"
check arm_fix_v4bx_interworking.stdout ".*08: .* bx r0"
# Test no fix.
check arm_no_fix_v4bx.stdout ".*00: .* bx r0"
check arm_no_fix_v4bx.stdout ".*04: .* bx pc"
exit 0