+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
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)
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;
}
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;
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
@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
@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:
--- /dev/null
+ .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
--- /dev/null
+#!/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