summaryrefslogtreecommitdiffstats
path: root/bfd/coff-arm.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2002-05-23 12:37:57 +0000
committerNick Clifton <nickc@redhat.com>2002-05-23 12:37:57 +0000
commitc62e1cc30f77e49b15d48d4d32c7f6c1e6827163 (patch)
tree7b9b45107783f709e9478e138286efc5c6682384 /bfd/coff-arm.c
parent6ff96af674ed8b5872e90def470405f90f8b4aac (diff)
downloadppe42-binutils-c62e1cc30f77e49b15d48d4d32c7f6c1e6827163.tar.gz
ppe42-binutils-c62e1cc30f77e49b15d48d4d32c7f6c1e6827163.zip
For the Thumb BLX reloc round the relocation up rather than down.
Diffstat (limited to 'bfd/coff-arm.c')
-rw-r--r--bfd/coff-arm.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index 1619e670c3..5e7f907a95 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -1701,21 +1701,23 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
|| signed_check < reloc_signed_min)
overflow = true;
- /* For the BLX(1) instruction remove bit 0 of the adjusted offset.
- Bit 0 can only be set if the upper insn is at a half-word boundary,
- since the destination address, an ARM instruction, must always be
- on a word boundary. The semantics of the BLX (1) instruction,
- however, are that bit 0 in the offset must always be 0, and the
- corresponding bit 1 in the target address will be set from bit
- 1 of the source address. */
- if ((x & 0x18000000) == 0x08000000)
- relocation &= ~0x2;
-
- /* Put the relocation into the correct bits. */
+ /* Put the relocation into the correct bits.
+ For a BLX instruction, make sure that the relocation is rounded up
+ to a word boundary. This follows the semantics of the instruction
+ which specifies that bit 1 of the target address will come from bit
+ 1 of the base address. */
if (bfd_big_endian (input_bfd))
- relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
+ {
+ if ((x & 0x1800) == 0x0800 && (relocation & 0x02))
+ relocation += 2;
+ relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
+ }
else
- relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
+ {
+ if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02))
+ relocation += 2;
+ relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
+ }
/* Add the relocation to the correct bits of X. */
x = ((x & ~howto->dst_mask) | relocation);
OpenPOWER on IntegriCloud