* reloc.c (_bfd_relocate_contents): Adjust handling of overflow to
authorIan Lance Taylor <ian@airs.com>
Sat, 26 Feb 1994 18:24:10 +0000 (18:24 +0000)
committerIan Lance Taylor <ian@airs.com>
Sat, 26 Feb 1994 18:24:10 +0000 (18:24 +0000)
avoid depending upon right shifts of signed numbers, and to
correct handling of src_mask with lower bits zero.

bfd/reloc.c

index 675bb2982cffc8ec1a22058592ac60974fa9ed65..4323d9aaf8a44315dc36c47c4017f0b1212b8750 100644 (file)
@@ -616,7 +616,8 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
          reloc_entry->address += input_section->output_offset;
 
          /* WTF?? */
-         if (abfd->xvec->flavour == bfd_target_coff_flavour) 
+         if (abfd->xvec->flavour == bfd_target_coff_flavour
+             && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0)
            {
 #if 1
              /* For m68k-coff, the addend was being subtracted twice during
@@ -1054,13 +1055,23 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
                               &~ ((bfd_vma) -1 >> howto->rightshift)));
        }
 
-      /* Add in the value from the object file, shifted down so that
-        it is a straight number.  */
+      /* Get the value from the object file.  */
       add = x & howto->src_mask;
-      if ((add & (((~ howto->src_mask) >> 1) & howto->src_mask)) == 0)
-       signed_add = add;
-      else
-       signed_add = add | ((bfd_vma) -1 &~ howto->src_mask);
+
+      /* Get the value from the object file with an appropriate sign.
+        The expression involving howto->src_mask isolates the upper
+        bit of src_mask.  If that bit is set in the value we are
+        adding, it is negative, and we subtract out that number times
+        two.  If src_mask includes the highest possible bit, then we
+        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 & (((~ howto->src_mask) >> 1) & howto->src_mask)) != 0)
+       signed_add -= (((~ howto->src_mask) >> 1) & howto->src_mask) << 1;
+
+      /* Add the value from the object file, shifted so that it is a
+        straight number.  */
       if (howto->bitpos == 0)
        {
          check += add;
@@ -1069,10 +1080,14 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
       else
        {
          check += add >> howto->bitpos;
+
+         /* For the signed case we use ADD, rather than SIGNED_ADD,
+            to avoid warnings from SVR4 cc.  This is OK since we
+            explictly handle the sign bits.  */
          if (signed_add >= 0)
-           signed_check += signed_add >> howto->bitpos;
+           signed_check += add >> howto->bitpos;
          else
-           signed_check += ((signed_add >> howto->bitpos)
+           signed_check += ((add >> howto->bitpos)
                             | ((bfd_vma) -1
                                &~ ((bfd_vma) -1 >> howto->bitpos)));
        }
@@ -1447,6 +1462,15 @@ CODE_FRAGMENT
 .  BFD_RELOC_386_GOTOFF,
 .  BFD_RELOC_386_GOTPC,
 .
+.  {* PowerPC/POWER (RS/6000) relocs.  *}
+.  {* 26 bit relative branch.  Low two bits must be zero.  High 24
+.     bits installed in bits 6 through 29 of instruction.  *}
+.  BFD_RELOC_PPC_B26,
+.  {* 26 bit absolute branch, like BFD_RELOC_PPC_B26 but absolute.  *}
+.  BFD_RELOC_PPC_BA26,
+.  {* 16 bit TOC relative reference.  *}
+.  BFD_RELOC_PPC_TOC16,
+.
 .  {* this must be the highest numeric value *}
 .  BFD_RELOC_UNUSED
 . } bfd_reloc_code_real_type;