2007-06-29 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Fri, 29 Jun 2007 15:05:47 +0000 (15:05 +0000)
committerPaul Brook <paul@codesourcery.com>
Fri, 29 Jun 2007 15:05:47 +0000 (15:05 +0000)
bfd/
* elf32-arm.c (bfd_elf32_arm_process_before_allocation): Suppress
call veneers for call relocations against undefined symbols.
(elf32_arm_final_link_relocate): Turn call to undefined symbol
into a jump to the next instruction.

ld/testuite/
* ld-arm/arm-elf.exp (armelftests): Add callweak.
* ld-arm/callweak.d: New test.
* ld-arm/callweak.s: New test.

bfd/ChangeLog
bfd/elf32-arm.c
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp

index ad71032..1f7f5c4 100644 (file)
@@ -1,3 +1,10 @@
+2007-06-29  Paul Brook  <paul@codesourcery.com>
+
+       * elf32-arm.c (bfd_elf32_arm_process_before_allocation): Suppress
+       call veneers for call relocations against undefined symbols.
+       (elf32_arm_final_link_relocate): Turn call to undefined symbol
+       into a jump to the next instruction.
+
 2007-06-29  Michael Snyder  <msnyder@svkmacdonelllnx>
 
        * bfd.c (bfd_demangle): Plug memory leak (Coverity).
index bf4f49f..a213bab 100644 (file)
@@ -3236,7 +3236,8 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
              /* This one is a call from thumb code.  We look
                 up the target of the call.  If it is not a thumb
                  target, we insert glue.  */
-             if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC && !globals->use_blx)
+             if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC && !globals->use_blx
+                 && h->root.type != bfd_link_hash_undefweak)
                record_thumb_to_arm_glue (link_info, h);
              break;
 
@@ -4812,40 +4813,43 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          signed_addend = value;
          signed_addend >>= howto->rightshift;
 
-         /* It is not an error for an undefined weak reference to be
-            out of range.  Any program that branches to such a symbol
-            is going to crash anyway, so there is no point worrying
-            about getting the destination exactly right.  */
-         if (! h || h->root.type != bfd_link_hash_undefweak)
+         /* A branch to an undefined weak symbol is turned into a jump to
+            the next instruction.  */
+         if (h && h->root.type == bfd_link_hash_undefweak)
+           {
+             value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000)
+                     | 0x0affffff;
+           }
+         else
            {
              /* Perform a signed range check.  */
              if (   signed_addend >   ((bfd_signed_vma)  (howto->dst_mask >> 1))
                  || signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
                return bfd_reloc_overflow;
-           }
 
-         addend = (value & 2);
+             addend = (value & 2);
 
-         value = (signed_addend & howto->dst_mask)
-           | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
+             value = (signed_addend & howto->dst_mask)
+               | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
 
-         /* Set the H bit in the BLX instruction.  */
-         if (sym_flags == STT_ARM_TFUNC)
-           {
-             if (addend)
-               value |= (1 << 24);
-             else
-               value &= ~(bfd_vma)(1 << 24);
-           }
-         if (r_type == R_ARM_CALL)
-           {
-             /* Select the correct instruction (BL or BLX).  */
+             /* Set the H bit in the BLX instruction.  */
              if (sym_flags == STT_ARM_TFUNC)
-               value |= (1 << 28);
-             else
                {
-                 value &= ~(bfd_vma)(1 << 28);
-                 value |= (1 << 24);
+                 if (addend)
+                   value |= (1 << 24);
+                 else
+                   value &= ~(bfd_vma)(1 << 24);
+               }
+             if (r_type == R_ARM_CALL)
+               {
+                 /* Select the correct instruction (BL or BLX).  */
+                 if (sym_flags == STT_ARM_TFUNC)
+                   value |= (1 << 28);
+                 else
+                   {
+                     value &= ~(bfd_vma)(1 << 28);
+                     value |= (1 << 24);
+                   }
                }
            }
          break;
@@ -5022,6 +5026,15 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        int bitsize;
        int thumb2 = using_thumb2 (globals);
 
+       /* A branch to an undefined weak symbol is turned into a jump to
+          the next instruction.  */
+       if (h && h->root.type == bfd_link_hash_undefweak)
+         {
+           bfd_put_16 (input_bfd, 0xe000, hit_data);
+           bfd_put_16 (input_bfd, 0xbf00, hit_data + 2);
+           return bfd_reloc_ok;
+         }
+
        /* Fetch the addend.  We use the Thumb-2 encoding (backwards compatible
            with Thumb-1) involving the J1 and J2 bits.  */
        if (globals->use_rel)
index f0a5de3..cd4281d 100644 (file)
@@ -1,3 +1,9 @@
+2007-06-29  Paul Brook  <paul@codesourcery.com>
+
+       * ld-arm/arm-elf.exp (armelftests): Add callweak.
+       * ld-arm/callweak.d: New test.
+       * ld-arm/callweak.s: New test.
+
 2007-06-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/4701
index 087225f..a83c1ee 100644 (file)
@@ -170,6 +170,9 @@ set armelftests {
      {"EABI attribute merging" "-r" "" {attr-merge.s attr-merge.s}
       {{readelf -A attr-merge.attr}}
       "attr-merge"}
+     {"callweak" "-static -T arm.ld" "" {callweak.s}
+      {{objdump -dr callweak.d}}
+      "callweak"}
 }
 
 run_ld_link_tests $armelftests