2S09-08-21 Daniel Gutson <dgutson@codesourcery.com>
authorDaniel Gutson <dgutson@codesourcery.com>
Fri, 21 Aug 2009 23:38:07 +0000 (23:38 +0000)
committerDaniel Gutson <dgutson@codesourcery.com>
Fri, 21 Aug 2009 23:38:07 +0000 (23:38 +0000)
ld/
        * ld-arm/callweak.d: Opcodes updated.
        * ld-arm/callweak.s: Architecture specified.
        * ld-arm/callweak-2.d: New test case.
        * ld-arm/callweak-2.s: New file.

bfd/
* elf32-arm.c (arch_has_thumb2_nop): New function.
(arch_has_arm_nop): New function.
(elf32_arm_final_link_relocate): NOP opcodes changed.

SVS: ----------------------------------------------------------------------

bfd/ChangeLog
bfd/elf32-arm.c
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/callweak-2.d [new file with mode: 0644]
ld/testsuite/ld-arm/callweak-2.s [new file with mode: 0644]
ld/testsuite/ld-arm/callweak.d
ld/testsuite/ld-arm/callweak.s

index f9c4c6de077f89e9a1188575451cffb50af81cbb..47f793f6469025eb3682f8e63605d9e0cfb936fd 100644 (file)
@@ -1,3 +1,9 @@
+2009-08-21  Daniel Gutson  <dgutson@codesourcery.com>
+
+       * elf32-arm.c (arch_has_thumb2_nop): New function.
+       (arch_has_arm_nop): New function.
+       (elf32_arm_final_link_relocate): NOP opcodes changed.
+
 2009-08-16  Doug Evans  <dje@google.com>
 
        * opncls.c (bfd_close): Until BFD_IN_MEMORY has an iovec,
index 49c80ad798e9eb44b00ec615bf9c50ce6a157ff9..5a0d9c37035c26411b9d4b77f5de4c8a4d3c0c6f 100644 (file)
@@ -2987,6 +2987,26 @@ using_thumb2 (struct elf32_arm_link_hash_table *globals)
   return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
 }
 
+/* Determine what kind of NOPs are available.  */
+
+static bfd_boolean
+arch_has_arm_nop (struct elf32_arm_link_hash_table *globals)
+{
+  const int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+                                            Tag_CPU_arch);
+  return arch == TAG_CPU_ARCH_V6T2
+        || arch == TAG_CPU_ARCH_V6K
+        || arch == TAG_CPU_ARCH_V7;
+}
+
+static bfd_boolean
+arch_has_thumb2_nop (struct elf32_arm_link_hash_table *globals)
+{
+  const int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+                                            Tag_CPU_arch);
+  return arch == TAG_CPU_ARCH_V6T2 || arch == TAG_CPU_ARCH_V7;
+}
+
 static bfd_boolean
 arm_stub_is_thumb (enum elf32_arm_stub_type stub_type)
 {
@@ -7073,13 +7093,19 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
          /* A branch to an undefined weak symbol is turned into a jump to
             the next instruction unless a PLT entry will be created.
-            Do the same for local undefined symbols.  */
+            Do the same for local undefined symbols.
+            The jump to the next instruction is optimized as a NOP depending
+            on the architecture.  */
          if (h ? (h->root.type == bfd_link_hash_undefweak
                   && !(splt != NULL && h->plt.offset != (bfd_vma) -1))
              : bfd_is_und_section (sym_sec))
            {
-             value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000)
-                     | 0x0affffff;
+             value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000);
+
+             if (arch_has_arm_nop (globals))
+               value |= 0x0320f000;
+             else
+               value |= 0x01a00000; /* Using pre-UAL nop: mov r0, r0.  */
            }
          else
            {
@@ -7324,15 +7350,25 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        bfd_vma check;
        bfd_signed_vma signed_check;
        int bitsize;
-       int thumb2 = using_thumb2 (globals);
+       const int thumb2 = using_thumb2 (globals);
 
        /* A branch to an undefined weak symbol is turned into a jump to
-          the next instruction unless a PLT entry will be created.  */
+          the next instruction unless a PLT entry will be created.
+          The jump to the next instruction is optimized as a NOP.W for
+          Thumb-2 enabled architectures.  */
        if (h && h->root.type == bfd_link_hash_undefweak
            && !(splt != NULL && h->plt.offset != (bfd_vma) -1))
          {
-           bfd_put_16 (input_bfd, 0xe000, hit_data);
-           bfd_put_16 (input_bfd, 0xbf00, hit_data + 2);
+           if (arch_has_thumb2_nop (globals))
+             {
+               bfd_put_16 (input_bfd, 0xf3af, hit_data);
+               bfd_put_16 (input_bfd, 0x8000, hit_data + 2);
+             }
+           else
+             {
+               bfd_put_16 (input_bfd, 0xe000, hit_data);
+               bfd_put_16 (input_bfd, 0xbf00, hit_data + 2);
+             }
            return bfd_reloc_ok;
          }
 
index 6f9bc27ab66e7bb668788215854c2674b0c20ce6..040ce8fa1b42f238d3a3a1d8c7561e2315071d1e 100644 (file)
@@ -1,3 +1,10 @@
+2009-08-21  Daniel Gutson  <dgutson@codesourcery.com>
+
+       * ld-arm/callweak.d: Opcodes updated.
+       * ld-arm/callweak.s: Architecture specified.
+       * ld-arm/callweak-2.d: New test case.
+       * ld-arm/callweak-2.s: New file.
+
 2009-08-17  Nick Clifton  <nickc@redhat.com>
 
        * ld-elf/linkonce1.d: Accept "UNUSED" as part of the name of an
diff --git a/ld/testsuite/ld-arm/callweak-2.d b/ld/testsuite/ld-arm/callweak-2.d
new file mode 100644 (file)
index 0000000..d401479
--- /dev/null
@@ -0,0 +1,15 @@
+
+.*:     file format.*
+
+Disassembly of section .far:
+
+12340000 <[^>]*>:
+12340000:      e320f000        nop     \{0\}
+12340004:      0320f000        nopeq   \{0\}
+
+12340008 <[^>]*>:
+12340008:      f3af 8000       nop.w
+1234000c:      2000            movs    r0, #0
+1234000e:      f3af 8000       nop.w
+12340012:      4770            bx      lr
+
diff --git a/ld/testsuite/ld-arm/callweak-2.s b/ld/testsuite/ld-arm/callweak-2.s
new file mode 100644 (file)
index 0000000..af4f026
--- /dev/null
@@ -0,0 +1,17 @@
+       .syntax unified
+       .arch armv6t2
+       .weak bar
+       .section .far, "ax", %progbits
+       .global _start
+       .type   _start, %function
+_start:
+       bl bar
+       bleq bar
+       .thumb
+       .type foo, %function
+       .thumb_func
+foo:
+       bl bar
+       movs r0, #0
+       bl bar
+       bx lr
index 3dffcc433e57960e720f5c5f6d64f484a5d88f56..89cb4a5cb72db8160167a7dabd2dd35206d69df5 100644 (file)
@@ -4,8 +4,8 @@
 Disassembly of section .far:
 
 12340000 <[^>]*>:
-12340000:      eaffffff        b       12340004 <[^>]*>
-12340004:      0affffff        beq     12340008 <[^>]*>
+12340000:      e1a00000        nop                     ; \(mov r0, r0\)
+12340004:      01a00000        moveq   r0, r0
 
 12340008 <[^>]*>:
 12340008:      e000            b.n     1234000c <[^>]*>
index 6850da3e6e60a674aa0d059bdb8a3e180d75e08d..b9bcd1bd299cb04142f779c53ee3551a380e607e 100644 (file)
@@ -1,4 +1,5 @@
        .syntax unified
+       .arch armv6
        .weak bar
        .section .far, "ax", %progbits
        .global _start