2010-02-26 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Sat, 27 Feb 2010 00:36:49 +0000 (00:36 +0000)
committerDoug Kwan <dougkwan@google.com>
Sat, 27 Feb 2010 00:36:49 +0000 (00:36 +0000)
* 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.

gold/ChangeLog
gold/arm.cc
gold/options.cc
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/arm_fix_v4bx.s [new file with mode: 0644]
gold/testsuite/arm_fix_v4bx.sh [new file with mode: 0755]

index 34b582ffa6c941df4bc77c2ca42b85da41c80f09..47bd8a791e9a26649386a91f4533179641342941 100644 (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
index 136fed630788a7cacac2e2d39cbe29e5e0f4a0bb..dde2d083c0df3d1f4b706a53041489eb0f220733 100644 (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;
        }
 
index f377387ed234ae6d22fa65e2e997649b507c1333..c6c8073683aa4be9c202f5b04f759904e5b49592 100644 (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;
index eaf544671985223f1863671c923dc8fab53fafb7..c9e2d1c45322f0e23f0ed35d6d491a9de3ca1d98 100644 (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
index bbffd69c86dde9d997b226d048979b67a303616d..10730f3098aefa8d8254e816564b2e640e86a9ea 100644 (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:
diff --git a/gold/testsuite/arm_fix_v4bx.s b/gold/testsuite/arm_fix_v4bx.s
new file mode 100644 (file)
index 0000000..fc3aa2a
--- /dev/null
@@ -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
diff --git a/gold/testsuite/arm_fix_v4bx.sh b/gold/testsuite/arm_fix_v4bx.sh
new file mode 100755 (executable)
index 0000000..a331ff9
--- /dev/null
@@ -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