diff options
author | Alan Modra <amodra@bigpond.net.au> | 2000-04-11 23:02:50 +0000 |
---|---|---|
committer | Alan Modra <amodra@bigpond.net.au> | 2000-04-11 23:02:50 +0000 |
commit | fd31a7e326949ef033e4ec42b10bee4b328eec4b (patch) | |
tree | 0ae3d7a75e8486a7610fa94dfc7b1bb0146ceed5 | |
parent | c12a62756e964933507447efbd5b4d0fcf379bb6 (diff) | |
download | gdb-fd31a7e326949ef033e4ec42b10bee4b328eec4b.tar.gz |
Allow address wrap for bitfields again.
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/reloc.c | 20 |
2 files changed, 17 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e1e1ec499a3..45c2b7b466b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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. diff --git a/bfd/reloc.c b/bfd/reloc.c index a3318e6c09a..ef2375a0d79 100644 --- a/bfd/reloc.c +++ b/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; |