mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 20:14:06 +08:00
Allow address wrap for bitfields again.
This commit is contained in:
parent
287e305808
commit
8a4ac87108
@ -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-11 Alan Modra <alan@linuxcare.com.au>
|
||||
|
||||
* coff-mips.c (mips_gprel_reloc): Test for 16 bit range using
|
||||
|
20
bfd/reloc.c
20
bfd/reloc.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user