From 35d220b53c6e263772ff133f3e81777ce552f6a7 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 23 May 2002 12:37:57 +0000 Subject: For the Thumb BLX reloc round the relocation up rather than down. --- bfd/coff-arm.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'bfd/coff-arm.c') 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); -- cgit v1.2.1