[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug in bfd relocation overflow handling

From: Chris Metcalf
Subject: bug in bfd relocation overflow handling
Date: Wed, 30 Nov 2005 15:02:25 -0500
User-agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)

It appears that if you have a 64-bit host targetting a 32-bit platform, the complain_overflow_bitfield case in _bfd_relocate_contents() will incorrectly generate an overflow error for negative constants. The "~fieldmask" gives you a whole lot of high one bits (for a 16-bit bitfield you get 0xffffffffffff0000). But, taking the value "a" to be some typical negative constant like -1 == 0xffffffff, ss becomes 0xffff0000, and doesn't equal ((bfd_vma) -1 >> rightshift) & signmask)) even though the expectation in this case is that it should. So I just cut signmask down with addrmask so it's 0xffff0000 instead (where addrmask is the mask for the target bitsize).

This bug is present in binutils-2.16.1.

Chris Metcalf

--- binutils-2.16.1/bfd/reloc.c.orig    2005-11-30 14:49:23.000000000 -0500
+++ binutils-2.16.1/bfd/reloc.c 2005-11-30 14:52:32.000000000 -0500
@@ -1504,21 +1504,21 @@

       case complain_overflow_bitfield:
         /* Much like the signed check, but for a field one bit
            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
            overflow, which is exactly what we want.  */
         a >>= rightshift;

-         signmask = ~ fieldmask;
+         signmask = (~ fieldmask) & addrmask;
         ss = a & signmask;
         if (ss != 0 && ss != (((bfd_vma) -1 >> rightshift) & signmask))
           flag = bfd_reloc_overflow;

         signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
         b = (b ^ signmask) - signmask;

         b >>= bitpos;

         sum = a + b;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]