Handle R_ARM_THM_PC11
authorNick Clifton <nickc@redhat.com>
Thu, 3 Jan 2002 14:23:01 +0000 (14:23 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 3 Jan 2002 14:23:01 +0000 (14:23 +0000)
bfd/ChangeLog
bfd/elf32-arm.h

index 25e1c6c..b5b8212 100644 (file)
@@ -1,3 +1,8 @@
+2002-01-03  Nick Clifton  <nickc@cambridge.redhat.com>
+
+       * elf32-arm.h (elf32_arm_final_link_relocate): Handle
+       R_ARM_THM_PC11 reloc.
+
 2002-01-02  Nick Clifton  <nickc@cambridge.redhat.com>
 
        * configure.in (LINGUAS): Add ja.
index afe3c8f..3a5939d 100644 (file)
@@ -1499,6 +1499,47 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
       }
       break;
 
+    case R_ARM_THM_PC11:
+      /* Thumb B (branch) instruction).  */
+      {
+       bfd_vma        relocation;
+       bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+       bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
+       bfd_vma        check;
+       bfd_signed_vma signed_check;
+
+#ifdef USE_REL
+       /* Need to refetch addend.  */
+       addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
+       /* ??? Need to determine shift amount from operand size.  */
+       addend >>= howto->rightshift;
+#endif
+       relocation = value + addend;
+
+       relocation -= (input_section->output_section->vma
+                      + input_section->output_offset
+                      + rel->r_offset);
+
+       check = relocation >> howto->rightshift;
+
+       /* If this is a signed value, the rightshift just
+          dropped leading 1 bits (assuming twos complement).  */
+       if ((bfd_signed_vma) relocation >= 0)
+         signed_check = check;
+       else
+         signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
+
+       relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask));
+       bfd_put_16 (input_bfd, relocation, hit_data);
+
+       /* Assumes two's complement.  */
+       if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
+         return bfd_reloc_overflow;
+
+       return bfd_reloc_ok;
+      }
+      
     case R_ARM_GNU_VTINHERIT:
     case R_ARM_GNU_VTENTRY:
       return bfd_reloc_ok;