]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Import changes from mainline into 2-11 branch
authorNick Clifton <nickc@redhat.com>
Thu, 14 Jun 2001 11:16:59 +0000 (11:16 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 14 Jun 2001 11:16:59 +0000 (11:16 +0000)
bfd/ChangeLog
bfd/coff-arm.c
bfd/config.bfd
bfd/elf32-arm.h

index a5107ec58ec072740088b35e0aa41b20e5f87586..d21c4a09fa884aed02cb460c3c21313fc17bb317 100644 (file)
@@ -1,3 +1,23 @@
+2001-06-14  Nick Clifton <nickc@redhat.com>
+
+       Merge from mainline sources:
+       2001-04-27  Sean McNeil <sean@mcneil.com>
+       * config.bfd: Add arm-vxworks target.
+       * coff-arm (coff_arm_relocate_section): Add in symbol value to
+       addend (fro VXworks targets).
+       2001-03-06  Nick Clifton  <nickc@redhat.com>
+       * elf32-arm.h (elf32_arm_final_link_relocate): Clear bit zero
+       of offset in BLX(1) instruction.
+       * coff-arm.c (coff_arm_relocate_section): Clear bit zero of
+       offset in BLX(1) instruction.
+        Fix formatting.
+       2001-03-06  Nick Clifton  <nickc@redhat.com>
+       * coff-arm.c (coff_arm_reloc_type_lookup): Add
+       BFD_RELOC_THUMB_PCREL_BLX.
+       2001-05-04  Nick Clifton  <nickc@cambridge.redhat.com>
+       * elf32-arm.h (elf32_arm_final_link_relocate): Set
+        EF_ARM_HASENTRY if the start address is set.
+
 2001-06-11  Alan Modra  <amodra@bigpond.net.au>
 
        * configure.in (<COREFILE case stmt>): Move powerpc-*-*bsd* after
index a315874b00f8435b91a6e4cc233119390f9b96e4..8bb4e6c4940b0fbaf45133af3bad7e9272ba257c 100644 (file)
@@ -854,6 +854,7 @@ coff_arm_reloc_type_lookup (abfd, code)
       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9,  ARM_THUMB9);
       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23);
+      ASTD (BFD_RELOC_THUMB_PCREL_BLX,      ARM_THUMB23);
 #endif
     default: return (CONST struct reloc_howto_struct *) 0;
     }
@@ -1243,12 +1244,18 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
         {
           if (info->relocateable)
             continue;
-#if 0  /* We must not ignore the symbol value.  If the symbol is
-         within the same section, the relocation should have already
-         been fixed, but if it is not, we'll be handed a reloc into
-         the beginning of the symbol's section, so we must not cancel
-         out the symbol's value, otherwise we'll be adding it in
-         twice.  */
+         /* FIXME - it is not clear which targets need this next test
+            and which do not.  It is known that it is needed for the
+            VXworks target (hence the #ifdef), but it is also known
+            that it was supressed for other (arm) targets.  This ought
+            to be sorted out one day.  */
+#ifdef VXWORKS
+         /* We must not ignore the symbol value.  If the symbol is
+            within the same section, the relocation should have already
+            been fixed, but if it is not, we'll be handed a reloc into
+            the beginning of the symbol's section, so we must not cancel
+            out the symbol's value, otherwise we'll be adding it in
+            twice.  */
           if (sym != NULL && sym->n_scnum != 0)
             addend += sym->n_value;
 #endif
@@ -1588,18 +1595,18 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
 
              BFD_ASSERT (size == 4);
 
-              /* howto->pc_relative should be TRUE for type 14 BRANCH23 */
+              /* howto->pc_relative should be TRUE for type 14 BRANCH23 */
               relocation -= (input_section->output_section->vma
                              + input_section->output_offset);
 
-              /* howto->pcrel_offset should be TRUE for type 14 BRANCH23 */
+              /* howto->pcrel_offset should be TRUE for type 14 BRANCH23 */
               relocation -= address;
 
              /* No need to negate the relocation with BRANCH23.  */
              /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23.  */
              /* howto->rightshift == 1 */
-             /* Drop unwanted bits from the value we are relocating to.  */
 
+             /* Drop unwanted bits from the value we are relocating to.  */
              check = relocation >> howto->rightshift;
 
              /* If this is a signed value, the rightshift just dropped
@@ -1613,13 +1620,9 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
 
              /* Get the value from the object file.  */
              if (bfd_big_endian (input_bfd))
-               {
-                 add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
-               }
+               add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
              else
-               {
-                 add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
-               }
+               add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
 
              /* Get the value from the object file with an appropriate sign.
                 The expression involving howto->src_mask isolates the upper
@@ -1629,18 +1632,16 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
                 can not get the upper bit, but that does not matter since
                 signed_add needs no adjustment to become negative in that
                 case.  */
-
              signed_add = add;
 
              if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
                signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
 
+             /* howto->bitpos == 0 */
              /* Add the value from the object file, shifted so that it is a
                 straight number.  */
-             /* howto->bitpos == 0 */
-
              signed_check += signed_add;
-             relocation += signed_add;
+             relocation   += signed_add;
 
              BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
 
@@ -1649,21 +1650,26 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
                  || signed_check < reloc_signed_min)
                overflow = true;
 
-             /* Put RELOCATION into the correct bits:  */
-
+             /* For the BLX(1) instruction remove bit 0 of the adjusted offset.
+                Bit 0 can only be set if the upper insn is at a half-word boundary,
+                since the destination address, an ARM instruction, must always be
+                on a word boundary.  The semantics of the BLX (1) instruction,
+                however, are that bit 0 in the offset must always be 0, and the
+                corresponding bit 1 in the target address will be set from bit
+                1 of the source address.  */
+             if ((x & 0x18000000) == 0x08000000)
+               relocation &= ~0x2;
+
+             /* Put the relocation into the correct bits.  */
              if (bfd_big_endian (input_bfd))
-               {
-                 relocation = (((relocation & 0xffe) >> 1)  | ((relocation << 4) & 0x07ff0000));
-               }
+               relocation = (((relocation & 0xffe) >> 1)  | ((relocation << 4) & 0x07ff0000));
              else
-               {
-                 relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
-               }
+               relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
 
-             /* Add RELOCATION to the correct bits of X:  */
+             /* Add the relocation to the correct bits of X.  */
              x = ((x & ~howto->dst_mask) | relocation);
 
-             /* Put the relocated value back in the object file:  */
+             /* Put the relocated value back in the object file.  */
              bfd_put_32 (input_bfd, x, location);
 
              rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
index 96d4cb7716050a1b359e764b76f14e3f085f11fe..c2eb27415428aa1c9c15e6b34356897997676e98 100644 (file)
@@ -139,6 +139,12 @@ case "${targ}" in
     targ_selvecs=armcoff_big_vec
     targ_underscore=yes
     ;;
+  arm-*-vxworks*)
+    targ_defvec=armcoff_little_vec
+    targ_selvecs=armcoff_big_vec
+    targ_underscore=yes
+    targ_cflags=-DVXWORKS
+    ;;
   arm-*-rtems*)
     targ_defvec=bfd_elf32_littlearm_vec
     targ_selvecs=bfd_elf32_bigarm_vec
index bfc4ca3c532e756f0845d65efacbdc3d0f3db062..66edd6d8e40ead416ae75e16882b063cce13cee5 100644 (file)
@@ -1019,6 +1019,18 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
   bfd_signed_vma                signed_addend;
   struct elf32_arm_link_hash_table * globals;
 
+  /* If the start address has been set, then set the EF_ARM_HASENTRY
+     flag.  Setting this more than once is redundant, but the cost is
+     not too high, and it keeps the code simple.
+     
+     The test is done  here, rather than somewhere else, because the
+     start address is only set just before the final link commences.
+
+     Note - if the user deliberately sets a start address of 0, the
+     flag will not be set.  */
+  if (bfd_get_start_address (output_bfd) != 0)
+    elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
+      
   globals = elf32_arm_hash_table (info);
 
   dynobj = elf_hash_table (info)->dynobj;
@@ -1434,6 +1446,18 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
        upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
        lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
 
+#ifndef OLD_ARM_ABI
+       if (r_type == R_ARM_THM_XPC22
+           && ((lower_insn & 0x1800) == 0x0800))
+         /* Remove bit zero of the adjusted offset.  Bit zero can only be
+            set if the upper insn is at a half-word boundary, since the
+            destination address, an ARM instruction, must always be on a
+            word boundary.  The semantics of the BLX (1) instruction, however,
+            are that bit zero in the offset must always be zero, and the
+            corresponding bit one in the target address will be set from bit
+            one of the source address.  */
+         lower_insn &= ~1;
+#endif 
        /* Put the relocated value back in the object file:  */
        bfd_put_16 (input_bfd, upper_insn, hit_data);
        bfd_put_16 (input_bfd, lower_insn, hit_data + 2);