]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Allow address wrap for bitfields again.
authorAlan Modra <amodra@gmail.com>
Tue, 11 Apr 2000 23:02:50 +0000 (23:02 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 11 Apr 2000 23:02:50 +0000 (23:02 +0000)
bfd/ChangeLog
bfd/reloc.c

index e1e1ec499a319a878ad1480c8a6235e0cbed0bd5..45c2b7b466b70ebbb823fc32b515034d5caceaa8 100644 (file)
@@ -1,3 +1,9 @@
+2000-04-12  Alan Modra  <alan@linuxcare.com.au>
+
+       * reloc.c (_bfd_relocate_contents): In complain_overflow_bitfield
+       case, allow address wrap-around stupidly removed 2000-03-17.  Sign
+       extend without an if statement.
+
 2000-04-04  Alan Modra  <alan@linuxcare.com.au>
 
        * po/bfd.pot: Regenerate.
index a3318e6c09ad47fda56e74617064316128add59e..ef2375a0d79013c2547beedafceb4c16e2a392cd 100644 (file)
@@ -1498,11 +1498,9 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
              trouble; we would need to verify that B is in range, as
              we do for A above.  */
          signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
-         if ((b & signmask) != 0)
-           {
-             /* Set all the bits above the sign bit.  */
-             b -= signmask << 1;
-           }
+
+         /* Set all the bits above the sign bit.  */
+         b = (b ^ signmask) - signmask;
 
          b = (b & addrmask) >> bitpos;
 
@@ -1545,7 +1543,7 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
 
        case complain_overflow_bitfield:
          /* Much like the signed check, but for a field one bit
-            wider, and no trimming with addrmask.  We allow a
+            wider, and no trimming inputs with addrmask.  We allow a
             bitfield to represent numbers in the range -2**n to
             2**n-1, where n is the number of bits in the field.
             Note that when bfd_vma is 32 bits, a 32-bit reloc can't
@@ -1558,15 +1556,19 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
            flag = bfd_reloc_overflow;
 
          signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
-         if ((b & signmask) != 0)
-           b -= signmask << 1;
+         b = (b ^ signmask) - signmask;
 
          b >>= bitpos;
 
          sum = a + b;
 
+         /* We mask with addrmask here to explicitly allow an address
+            wrap-around.  The Linux kernel relies on it, and it is
+            the only way to write assembler code which can run when
+            loaded at a location 0x80000000 away from the location at
+            which it is linked.  */
          signmask = fieldmask + 1;
-         if (((~ (a ^ b)) & (a ^ sum)) & signmask)
+         if (((~ (a ^ b)) & (a ^ sum)) & signmask & addrmask)
            flag = bfd_reloc_overflow;
 
          break;