* elf32-arm.h (elf32_arm_final_link_relocate case R_ARM_GOTOFF)
authorRichard Earnshaw <richard.earnshaw@arm.com>
Thu, 21 Mar 2002 15:26:03 +0000 (15:26 +0000)
committerRichard Earnshaw <richard.earnshaw@arm.com>
Thu, 21 Mar 2002 15:26:03 +0000 (15:26 +0000)
(case R_ARM_GOT): Handle relocations to Thumb functions.

bfd/ChangeLog
bfd/elf32-arm.h

index bbff31d4fc9c1163ae18fce907f3f9c72895d736..884499405a6f7daeba87cd7f937b0e8e3ae7d242 100644 (file)
@@ -1,3 +1,8 @@
+2002-03-21  Richard Earnshaw  <rearnsha@arm.com>
+
+       * elf32-arm.h (elf32_arm_final_link_relocate case R_ARM_GOTOFF)
+       (case R_ARM_GOT): Handle relocations to Thumb functions.
+
 2002-03-21  Alan Modra  <amodra@bigpond.net.au>
 
        * coff64-rs6000.c (_bfd_xcoff64_put_symbol_name): Prototype.
index a452465ead2de0f8a0fc6b5355d96a69eab5dc0b..04965412a00ec650ce16f775106b7a67218d39b2 100644 (file)
@@ -1560,6 +1560,12 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
       if (sgot == NULL)
         return bfd_reloc_notsupported;
 
+      /* If we are addressing a Thumb function, we need to adjust the 
+        address by one, so that attempts to call the function pointer will
+        correctly interpret it as Thumb code.  */
+      if (sym_flags == STT_ARM_TFUNC)
+       value += 1;
+
       /* Note that sgot->output_offset is not involved in this
          calculation.  We always want the start of .got.  If we
          define _GLOBAL_OFFSET_TABLE in a different way, as is
@@ -1612,6 +1618,13 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                off &= ~1;
              else
                {
+                 /* If we are addressing a Thumb function, we need to
+                    adjust the address by one, so that attempts to
+                    call the function pointer will correctly
+                    interpret it as Thumb code.  */
+                 if (sym_flags == STT_ARM_TFUNC)
+                   value |= 1;
+
                  bfd_put_32 (output_bfd, value, sgot->contents + off);
                  h->got.offset |= 1;
                }